Skip to content

Commit c9de01e

Browse files
committed
feat: add support for updating form
1 parent 5468522 commit c9de01e

File tree

5 files changed

+86
-58
lines changed

5 files changed

+86
-58
lines changed

docs/apis/GuiAPI/Form.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ for a specific player object `pl`, the following form interfaces are available:
1313

1414
A modal form contains a title, a text display, and two buttons.
1515

16-
`pl.sendModalForm(title,content,confirmButton,cancelButton,callback)`
16+
`pl.sendModalForm(title,content,confirmButton,cancelButton,callback,forUpdating)`
1717

1818
- Parameters:
1919
- title : `String`
@@ -26,6 +26,8 @@ A modal form contains a title, a text display, and two buttons.
2626
Button 2 text.
2727
- callback : `Function`
2828
Function called after player clicks a button.
29+
- forUpdating : `Boolean`
30+
Whether the form is sent for updating.
2931
- Return value: The ID of the sent form.
3032
- Return value type: `Integer`
3133
- If the return value is `Null`, it means the sending failed.
@@ -49,7 +51,7 @@ set.
4951
Due to the relatively complex content setup of buttons, it is recommended to use the form builder API in the next
5052
section to better accomplish this task.
5153

52-
`pl.sendSimpleForm(title,content,buttons,images,callback)`
54+
`pl.sendSimpleForm(title,content,buttons,images,callback,forUpdating)`
5355

5456
- Parameters:
5557
- title : `String`
@@ -62,6 +64,8 @@ section to better accomplish this task.
6264
Image path corresponding to each button.
6365
- callback : `Function`
6466
The function called after the player clicks a button.
67+
- forUpdating : `Boolean`
68+
Whether the form is sent for updating.
6569
- Return value: The sent form ID.
6670
- Return value type: `Integer`
6771
- If the return value is `Null`, it means the sending failed.
@@ -91,13 +95,15 @@ Custom forms can contain rich custom controls.
9195
Since the relevant JSON definition format is relatively complex, it is recommended to use the form builder API in the
9296
next section to better accomplish this task.
9397

94-
`pl.sendCustomForm(json,callback)`
98+
`pl.sendCustomForm(json,callback,forUpdating)`
9599

96100
- Parameters:
97101
- json : `String`
98102
Custom form JSON string.
99103
- callback : `Function`
100104
Callback function to be called after the player submits the form.
105+
- forUpdating : `Boolean`
106+
Whether the form is sent for updating.
101107
- Return value: The sent form ID.
102108
- Return value type: `Integer`
103109
- If the return value is Null, it means the sending failed.

docs/apis/GuiAPI/Form.zh.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
模式表单包含一个标题、一个文本显示框以及两个按钮
1414

15-
`pl.sendModalForm(title,content,confirmButton,cancelButton,callback)`
15+
`pl.sendModalForm(title,content,confirmButton,cancelButton,callback,forUpdating)`
1616

1717
- 参数:
1818
- title : `String`
@@ -25,6 +25,8 @@
2525
按钮2文本的字符串
2626
- callback : `Function`
2727
玩家点击按钮之后被调用的回调函数。
28+
- forUpdating : `Boolean`
29+
是否为表单更新
2830
- 返回值:发送的表单ID
2931
- 返回值类型:`Integer`
3032
- 如果返回值为`Null`,则代表发送失败
@@ -46,7 +48,7 @@
4648
普通表单包含一个标题、一个文本显示框以及若干按钮,可以设置按钮上显示的图标
4749
由于按钮的内容设置相对复杂,建议使用下一节的表单构建器API更好地完成这项任务。
4850

49-
`pl.sendSimpleForm(title,content,buttons,images,callback)`
51+
`pl.sendSimpleForm(title,content,buttons,images,callback,forUpdating)`
5052

5153
- 参数:
5254
- title : `String`
@@ -59,6 +61,8 @@
5961
各个按钮对应的图片路径
6062
- callback : `Function`
6163
玩家点击按钮之后被调用的回调函数。
64+
- forUpdating : `Boolean`
65+
是否为表单更新。
6266
- 返回值:发送的表单ID
6367
- 返回值类型:`Integer`
6468
- 如果返回值为`Null`,则代表发送失败
@@ -87,13 +91,15 @@
8791
自定义表单可以包含丰富的自定义控件。
8892
由于相关JSON定义格式相对复杂,建议使用下一节的表单构建器API更好地完成这项任务。
8993

90-
`pl.sendCustomForm(json,callback)`
94+
`pl.sendCustomForm(json,callback,forUpdating)`
9195

9296
- 参数:
9397
- json : `String`
9498
自定义表单json字符串
9599
- callback : `Function`
96100
玩家提交表单之后被调用的回调函数。
101+
- forUpdating : `Boolean`
102+
是否为表单更新。
97103
- 返回值:发送的表单ID
98104
- 返回值类型:`Integer`
99105
- 如果返回值为`Null`,则代表发送失败

docs/apis/GuiAPI/FormBuilder.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,15 @@ are called when there is player interaction, without fighting.
9393

9494
For a player object `pl`, using the function:
9595

96-
`pl.sendForm(fm,callback)`
96+
`pl.sendForm(fm,callback.forUpdating)`
9797

9898
- Parameters:
9999
- fm : `SimpleForm`
100100
The configured form object.
101101
- callback : `Function`
102102
Callback function to be called after the player interacts with the form element.
103+
- forUpdating : `Boolean`
104+
Whether the form is sent for updating.
103105
- Return value: The sent form ID.
104106
- Return value type: `Integer`
105107
- If the return value is `Null`, it means the sending failed.
@@ -263,13 +265,15 @@ are called when there is player interaction, without fighting.
263265

264266
For a player object `pl`, using the function:
265267

266-
`pl.sendForm(fm,callback)`
268+
`pl.sendForm(fm,callback,forUpdating)`
267269

268270
- Parameters:
269271
- fm : `CustomForm`
270272
Configured custom form object.
271273
- callback : `Function`
272274
Callback function to be called after the player submits the form.
275+
- forUpdating : `Boolean`
276+
Whether the form is sent for updating.
273277
- Return value: The sent form ID.
274278
- Return value type: `Integer`
275279
- If the return value is `Null`, it means the sending failed.

docs/apis/GuiAPI/FormBuilder.zh.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,13 +93,15 @@
9393

9494
对于某个玩家对象`pl`,使用函数:
9595

96-
`pl.sendForm(fm,callback)`
96+
`pl.sendForm(fm,callback,forUpdating)`
9797

9898
- 参数:
9999
- fm : `SimpleForm`
100100
配置好的表单对象
101101
- callback : `Function`
102102
玩家与表单元素互动之后被调用的回调函数。
103+
- forUpdating : `Boolean`
104+
是否为表单更新
103105
- 返回值:发送的表单ID
104106
- 返回值类型:`Integer`
105107
- 如果返回值为`Null`,则代表发送失败
@@ -260,13 +262,15 @@ reason可能会是`null`.
260262

261263
对于某个玩家对象`pl`,使用函数:
262264

263-
`pl.sendForm(fm,callback)`
265+
`pl.sendForm(fm,callback,forUpdating)`
264266

265267
- 参数:
266268
- fm : `CustomForm`
267269
配置好的自定义表单对象
268270
- callback : `Function`
269271
玩家提交表单之后被调用的回调函数。
272+
- forUpdating : `Boolean`
273+
是否为表单更新
270274
- 返回值:发送的表单ID
271275
- 返回值类型:`Integer`
272276
- 如果返回值为`Null`,则代表发送失败

src/legacy/api/PlayerAPI.cpp

Lines changed: 56 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#include "mc/network/ConnectionRequest.h"
4646
#include "mc/network/MinecraftPacketIds.h"
4747
#include "mc/network/MinecraftPackets.h"
48+
#include "mc/network/NetEventCallback.h"
4849
#include "mc/network/ServerNetworkHandler.h"
4950
#include "mc/network/packet/BossEventPacket.h"
5051
#include "mc/network/packet/LevelChunkPacket.h"
@@ -2435,16 +2436,18 @@ Local<Value> PlayerClass::removeBossBar(const Arguments& args) {
24352436
}
24362437

24372438
Local<Value> PlayerClass::sendSimpleForm(const Arguments& args) {
2438-
CHECK_ARGS_COUNT(args, 4);
2439+
CHECK_ARGS_COUNT(args, 5);
24392440
CHECK_ARG_TYPE(args[0], ValueKind::kString);
24402441
CHECK_ARG_TYPE(args[1], ValueKind::kString);
24412442
CHECK_ARG_TYPE(args[2], ValueKind::kArray);
24422443
CHECK_ARG_TYPE(args[3], ValueKind::kArray);
24432444
CHECK_ARG_TYPE(args[4], ValueKind::kFunction);
2445+
if (args.size() > 5) CHECK_ARG_TYPE(args[5], ValueKind::kBoolean);
24442446

24452447
try {
24462448
Player* player = get();
24472449
if (!player) return Local<Value>();
2450+
bool update = args.size() > 5 ? args[5].asBoolean().value() : false;
24482451

24492452
// 普通格式
24502453
auto textsArr = args[2].asArray();
@@ -2463,26 +2466,25 @@ Local<Value> PlayerClass::sendSimpleForm(const Arguments& args) {
24632466
form.appendButton(textsArr.get(i).asString().toString());
24642467
}
24652468
}
2466-
form.sendTo(
2467-
*player,
2468-
[engine{EngineScope::currentEngine()},
2469-
callback{script::Global(args[4].asFunction())
2470-
}](Player& pl, int chosen, ll::form::FormCancelReason reason) {
2471-
if ((ll::getGamingStatus() != ll::GamingStatus::Running)) return;
2472-
if (!EngineManager::isValid(engine)) return;
2473-
2474-
EngineScope scope(engine);
2475-
try {
2476-
callback.get().call(
2477-
{},
2478-
PlayerClass::newPlayer(&pl),
2479-
chosen >= 0 ? Number::newNumber(chosen) : Local<Value>(),
2480-
reason.has_value() ? Number::newNumber((uchar)reason.value()) : Local<Value>()
2481-
);
2482-
}
2483-
CATCH_IN_CALLBACK("sendSimpleForm")
2469+
auto formCallback = [engine{EngineScope::currentEngine()},
2470+
callback{script::Global(args[4].asFunction())
2471+
}](Player& pl, int chosen, ll::form::FormCancelReason reason) {
2472+
if ((ll::getGamingStatus() != ll::GamingStatus::Running)) return;
2473+
if (!EngineManager::isValid(engine)) return;
2474+
2475+
EngineScope scope(engine);
2476+
try {
2477+
callback.get().call(
2478+
{},
2479+
PlayerClass::newPlayer(&pl),
2480+
chosen >= 0 ? Number::newNumber(chosen) : Local<Value>(),
2481+
reason.has_value() ? Number::newNumber((uchar)reason.value()) : Local<Value>()
2482+
);
24842483
}
2485-
);
2484+
CATCH_IN_CALLBACK("sendSimpleForm")
2485+
};
2486+
if (update) form.sendUpdate(*player, std::move(formCallback));
2487+
else form.sendTo(*player, std::move(formCallback));
24862488

24872489
return Number::newNumber(1);
24882490
}
@@ -2496,37 +2498,40 @@ Local<Value> PlayerClass::sendModalForm(const Arguments& args) {
24962498
CHECK_ARG_TYPE(args[2], ValueKind::kString);
24972499
CHECK_ARG_TYPE(args[3], ValueKind::kString);
24982500
CHECK_ARG_TYPE(args[4], ValueKind::kFunction);
2501+
if (args.size() > 5) CHECK_ARG_TYPE(args[5], ValueKind::kBoolean);
24992502

25002503
try {
25012504
Player* player = get();
25022505
if (!player) return Local<Value>();
2506+
bool update = args.size() > 5 ? args[5].asBoolean().value() : false;
25032507

25042508
ll::form::ModalForm form(
25052509
args[0].asString().toString(),
25062510
args[1].asString().toString(),
25072511
args[2].asString().toString(),
25082512
args[3].asString().toString()
25092513
);
2510-
form.sendTo(
2511-
*player,
2512-
[engine{EngineScope::currentEngine()},
2513-
callback{script::Global(args[4].asFunction())
2514-
}](Player& pl, ll::form::ModalFormResult const& chosen, ll::form::FormCancelReason reason) {
2515-
if ((ll::getGamingStatus() != ll::GamingStatus::Running)) return;
2516-
if (!EngineManager::isValid(engine)) return;
2517-
2518-
EngineScope scope(engine);
2519-
try {
2520-
callback.get().call(
2521-
{},
2522-
PlayerClass::newPlayer(&pl),
2523-
chosen ? Boolean::newBoolean(static_cast<bool>(*chosen)) : Local<Value>(),
2524-
reason.has_value() ? Number::newNumber((uchar)reason.value()) : Local<Value>()
2525-
);
2526-
}
2527-
CATCH_IN_CALLBACK("sendModalForm")
2514+
auto formCallback = [engine{EngineScope::currentEngine()},
2515+
callback{script::Global(args[4].asFunction())
2516+
}](Player& pl, ll::form::ModalFormResult const& chosen, ll::form::FormCancelReason reason
2517+
) {
2518+
if ((ll::getGamingStatus() != ll::GamingStatus::Running)) return;
2519+
if (!EngineManager::isValid(engine)) return;
2520+
2521+
EngineScope scope(engine);
2522+
try {
2523+
callback.get().call(
2524+
{},
2525+
PlayerClass::newPlayer(&pl),
2526+
chosen ? Boolean::newBoolean(static_cast<bool>(*chosen)) : Local<Value>(),
2527+
reason.has_value() ? Number::newNumber((uchar)reason.value()) : Local<Value>()
2528+
);
25282529
}
2529-
);
2530+
CATCH_IN_CALLBACK("sendModalForm")
2531+
};
2532+
2533+
if (update) form.sendUpdate(*player, std::move(formCallback));
2534+
else form.sendTo(*player, std::move(formCallback));
25302535

25312536
return Number::newNumber(2);
25322537
}
@@ -2537,20 +2542,19 @@ Local<Value> PlayerClass::sendCustomForm(const Arguments& args) {
25372542
CHECK_ARGS_COUNT(args, 2);
25382543
CHECK_ARG_TYPE(args[0], ValueKind::kString);
25392544
CHECK_ARG_TYPE(args[1], ValueKind::kFunction);
2545+
if (args.size() > 2) CHECK_ARG_TYPE(args[2], ValueKind::kBoolean);
25402546

25412547
try {
25422548
Player* player = get();
25432549
if (!player) return Local<Value>();
2550+
bool update = args.size() > 2 ? args[2].asBoolean().value() : false;
25442551

25452552
auto formData = ordered_json::parse(args[0].asString().toString());
2546-
ll::form::Form::sendRawTo(
2547-
*player,
2548-
formData.dump(),
2553+
auto formCallback =
25492554
[id{player->getOrCreateUniqueID()},
25502555
engine{EngineScope::currentEngine()},
25512556
callback{script::Global(args[1].asFunction())},
2552-
formData = std::move(formData
2553-
)](Player& player, std::optional<std::string> const& result, ll::form::FormCancelReason reason) {
2557+
formData](Player& player, std::optional<std::string> const& result, ll::form::FormCancelReason reason) {
25542558
if ((ll::getGamingStatus() != ll::GamingStatus::Running)) return;
25552559
if (!EngineManager::isValid(engine)) return;
25562560
auto newResult = lse::form::CustomFormWrapper::convertResult(result, formData);
@@ -2565,8 +2569,10 @@ Local<Value> PlayerClass::sendCustomForm(const Arguments& args) {
25652569
);
25662570
}
25672571
CATCH_IN_CALLBACK("sendCustomForm")
2568-
}
2569-
);
2572+
};
2573+
if (update) ll::form::Form::sendRawUpdate(*player, formData.dump(), std::move(formCallback));
2574+
else ll::form::Form::sendRawTo(*player, formData.dump(), std::move(formCallback));
2575+
25702576
return Number::newNumber(3);
25712577
} catch (const ordered_json::exception& e) {
25722578
lse::LegacyScriptEngine::getInstance().getSelf().getLogger().error(
@@ -2581,17 +2587,19 @@ Local<Value> PlayerClass::sendCustomForm(const Arguments& args) {
25812587
Local<Value> PlayerClass::sendForm(const Arguments& args) {
25822588
CHECK_ARGS_COUNT(args, 2);
25832589
CHECK_ARG_TYPE(args[1], ValueKind::kFunction);
2590+
if (args.size() > 2) CHECK_ARG_TYPE(args[2], ValueKind::kBoolean);
25842591

25852592
try {
25862593
Player* player = get();
25872594
if (!player) return Local<Value>();
2595+
bool update = args.size() > 2 ? args[2].asBoolean().value() : false;
25882596

25892597
if (IsInstanceOf<SimpleFormClass>(args[0])) {
25902598
Local<Function> callback = args[1].asFunction();
2591-
SimpleFormClass::sendForm(SimpleFormClass::extract(args[0]), player, callback);
2599+
SimpleFormClass::sendForm(SimpleFormClass::extract(args[0]), player, callback, update);
25922600
} else if (IsInstanceOf<CustomFormClass>(args[0])) {
25932601
Local<Function> callback = args[1].asFunction();
2594-
CustomFormClass::sendForm(CustomFormClass::extract(args[0]), player, callback);
2602+
CustomFormClass::sendForm(CustomFormClass::extract(args[0]), player, callback, update);
25952603
} else {
25962604
LOG_WRONG_ARG_TYPE(__FUNCTION__);
25972605
return Local<Value>();

0 commit comments

Comments
 (0)