├── ApiFloodgate.sk ├── ApiGeyserUtils.sk ├── LICENSE └── README.md /ApiFloodgate.sk: -------------------------------------------------------------------------------- 1 | # The skript depends on plugins: 2 | # Skript 3 | # Skript-Reflect 4 | # Floodgate 5 | # and you don't need Floodgate-Skript any more 6 | 7 | import: 8 | org.bukkit.Bukkit 9 | org.bukkit.entity.Player 10 | 11 | org.geysermc.floodgate.api.FloodgateApi 12 | org.geysermc.cumulus.form.SimpleForm 13 | org.geysermc.cumulus.form.ModalForm 14 | org.geysermc.cumulus.form.CustomForm 15 | org.geysermc.cumulus.form.util.FormBuilder 16 | org.geysermc.cumulus.util.FormImage 17 | org.geysermc.cumulus.util.FormImage$Type 18 | 19 | java.util.function.BiConsumer 20 | java.util.function.Consumer 21 | 22 | 23 | on load: 24 | delete {floodgateApiCache::*} 25 | set {_floodgate_skript} to Bukkit.getPluginManager().getPlugin("Floodgate-Skript") 26 | if {_floodgate_skript} is set: 27 | send "&cYou don't need Floodgate-Skript any more" to console 28 | loop all players: 29 | setFloodgateData(loop-player) 30 | 31 | on unload: 32 | delete {floodgateApiCache::*} 33 | 34 | function saveFloodgatePlayerInfo(p: player, type: string, info: string): 35 | set {floodgateApiCache::%{_p}'s uuid%::%{_type}%} to {_info} 36 | 37 | on connect with priority lowest: 38 | set {_p} to player 39 | setFloodgateData({_p}) 40 | 41 | function setFloodgateData(p: player): 42 | set {_fp} to FloodgateApi.getInstance().getPlayer({_p}.getUniqueId()) 43 | if {_fp} is set: 44 | set {_locate} to {_fp}.getLanguageCode() 45 | set {_device} to {_fp}.getDeviceOs().toString() 46 | set {_version} to {_fp}.getVersion() 47 | set {_ui} to {_fp}.getUiProfile().toString() 48 | set {floodgateApiCache::%{_p}'s uuid%::bedrock} to true 49 | else: 50 | set {_locate} to "Java" 51 | set {_version} to "Java" 52 | set {_device} to "Java" 53 | set {_ui} to "JAVA" 54 | 55 | saveFloodgatePlayerInfo({_p}, "ui", {_ui}) 56 | saveFloodgatePlayerInfo({_p}, "locate", {_locate}) 57 | saveFloodgatePlayerInfo({_p}, "device", {_device}) 58 | saveFloodgatePlayerInfo({_p}, "version", {_version}) 59 | 60 | 61 | condition %player% (1¦is|2¦is(n't| not)) [from] floodgate: 62 | check: 63 | set {_p} to expr-1 64 | if mark is 1: 65 | if {floodgateApiCache::%{_p}'s uuid%::bedrock} is true: 66 | continue 67 | else if mark is 2: 68 | if {floodgateApiCache::%{_p}'s uuid%::bedrock} isn't true: 69 | continue 70 | 71 | 72 | expression [the] [bedrock] (locale|language) of [the] [floodgate] %player%: 73 | return type: string 74 | get: 75 | set {_p} to expr-1 76 | return {floodgateApiCache::%uuid of {_p}%::locate} 77 | 78 | expression [the] [bedrock] (platform|device) of [the] [floodgate] %player%: 79 | return type: string 80 | get: 81 | set {_p} to expr-1 82 | return {floodgateApiCache::%uuid of {_p}%::device} 83 | 84 | expression [the] [bedrock] version of [the] [floodgate] %player%: 85 | return type: string 86 | get: 87 | set {_p} to expr-1 88 | return {floodgateApiCache::%uuid of {_p}%::version} 89 | 90 | expression [the] [bedrock] ui [profile] of [the] [floodgate] %player%: 91 | return type: string 92 | get: 93 | set {_p} to expr-1 94 | return {floodgateApiCache::%uuid of {_p}%::ui} 95 | 96 | 97 | on quit: 98 | delete {floodgateApiCache::%player's uuid%::*} 99 | 100 | 101 | 102 | 103 | 104 | expression [clicked] button id of %object%: 105 | return type: number 106 | get: 107 | return expr-1.clickedButtonId() 108 | 109 | 110 | custom event "close form": 111 | pattern: form close 112 | event-values: player 113 | 114 | 115 | custom event "submit custom form": 116 | pattern: submit custom form 117 | event-values: player 118 | 119 | 120 | custom event "click button of form": 121 | pattern: click form button 122 | event-values: player 123 | 124 | 125 | expression [the] simple form with title %string%: 126 | return type: object 127 | get: 128 | set {_F} to SimpleForm.builder().title(expr-1) 129 | return {_F} 130 | 131 | expression [the] custom form with title %string%: 132 | return type: object 133 | get: 134 | set {_F} to CustomForm.builder().title(expr-1) 135 | return {_F} 136 | 137 | 138 | expression [the] modal form with title %string% and button[s] %string% %string%: 139 | return type: object 140 | get: 141 | set {_F} to ModalForm.builder().title(expr-1) 142 | {_F}.button1(expr-2).button2(expr-3) 143 | return {_F} 144 | 145 | 146 | 147 | expression [the] dropdown [component] display[s] %string% with [the] option[s] %strings%: 148 | return type: strings 149 | get: 150 | set {_a::*} to expr-2 151 | set {_s::1} to "dropdown" 152 | set {_s::2} to expr-1 153 | set {_s::3} to join {_a::*} by "[;;]" 154 | return {_s::*} 155 | 156 | 157 | expression [the] toggle [component] display[s] %string%[ with( | state )%-boolean%]: 158 | return type: strings 159 | get: 160 | set {_s::1} to "toggle" 161 | set {_s::2} to expr-1 162 | if expr-2 is set: 163 | set {_s::3} to "%expr-2%" 164 | return {_s::*} 165 | 166 | 167 | expression [the] input [component] display[s] %string% with placeholder %string% and (text|default text) %string%: 168 | return type: strings 169 | get: 170 | set {_s::1} to "input" 171 | set {_s::2} to expr-1 172 | set {_s::3} to expr-2 173 | set {_s::4} to expr-3 174 | return {_s::*} 175 | 176 | expression [the] slider component display[s] %string% with min[imum] [value] %number%(,| ,|, )max[imum] [value] %number%(,| ,|, )step %number%(,| ,|, )default [value] %number%: 177 | return type: strings 178 | get: 179 | set {_s::1} to "slider" 180 | set {_s::2} to expr-1 181 | set {_s::3} to "%expr-2%" 182 | set {_s::4} to "%expr-3%" 183 | set {_s::5} to "%expr-4%" 184 | set {_s::6} to "%expr-5%" 185 | return {_s::*} 186 | 187 | 188 | expression [the] step slider display[s] %string% default step %number% with steps %strings%: 189 | return type: objects 190 | get: 191 | set {_steps::*} to expr-3 192 | set {_s::1} to "step_slider" 193 | set {_s::2} to expr-1 194 | set {_s::3} to expr-2 195 | set {_s::4} to join {_steps::*} by "[;;]" 196 | return {_s::*} 197 | 198 | 199 | expression input component [with] id %number% of [response ]%object%: 200 | return type: string 201 | get: 202 | set {_r} to expr-2.asInput(expr-1) 203 | return {_r} 204 | 205 | 206 | expression toggle component [with] id %number% of [response] %object%: 207 | return type: boolean 208 | get: 209 | set {_r} to expr-2.asToggle(expr-1) 210 | return {_r} 211 | 212 | 213 | expression slider component [with] id %number% of [response] %object%: 214 | return type: number 215 | get: 216 | set {_r} to expr-2.asSlider(expr-1) 217 | return {_r} 218 | 219 | 220 | expression step slide[r] component [with] id %number% of [response] %object%: 221 | return type: number 222 | get: 223 | set {_r} to expr-2.asStepSlider(expr-1) 224 | return {_r} 225 | 226 | 227 | expression dropdown component [with] id %number% of [response] %object%: 228 | return type: number 229 | get: 230 | set {_r} to expr-2.asDropdown(expr-1) 231 | return {_r} 232 | 233 | 234 | expression form title of [response] %object%: 235 | return type: string 236 | get: 237 | set {_r} to expr-1.title() 238 | return {_r} 239 | 240 | 241 | expression component [with] id %number% of [response] %object%: 242 | return type: object 243 | get: 244 | 245 | return expr-2.valueAt(expr-1) 246 | 247 | 248 | effect add %objects% to [form] %object%: 249 | trigger: 250 | set {_a::*} to expr-1 251 | if {_a::1} is "dropdown": 252 | set {_opt::*} to split {_a::3} by "[;;]" 253 | expr-2.dropdown({_a::2}, [{_opt::*}]) 254 | else if {_a::1} is "input": 255 | expr-2.input({_a::2}, {_a::3}, {_a::4}) 256 | else if {_a::1} is "toggle": 257 | if {_a::3} is set: 258 | set {_boolean} to {_a::3} parsed as boolean 259 | else: 260 | set {_boolean} to false 261 | expr-2.toggle({_a::2}, {_boolean}) 262 | else if {_a::1} is "slider": 263 | set {_min} to {_a::3} parsed as number 264 | set {_max} to {_a::4} parsed as number 265 | set {_step} to {_a::5} parsed as number 266 | set {_default} to {_a::6} parsed as number 267 | expr-2.slider({_a::2}, {_min}, {_max}, {_step}, {_default}) 268 | else if {_a::1} is "step_slider": 269 | set {_steps::*} to {_a::4} split by "[;;]" 270 | expr-2.stepSlider({_a::2}, {_a::3}, [{_steps::*} as String]) 271 | else if {_a::1} is "path_icon": 272 | expr-2.iconPath({_a::2}) 273 | else if {_a::1} is "url_icon": 274 | expr-2.iconUrl({_a::2}) 275 | else: 276 | set {_s::*} to split {_a::1} by "[;;]" 277 | if {_s::1} is "url": 278 | expr-2.button({_s::2}, Type.URL, {_s::3}) 279 | else if {_s::1} is "path": 280 | expr-2.button({_s::2}, Type.PATH, {_s::3}) 281 | else if {_s::1} is "none": 282 | expr-2.button({_s::2}) 283 | else if {_s::1} is "content": 284 | expr-2.content({_s::2}) 285 | else if {_s::1} is "label": 286 | expr-2.label({_s::2}) 287 | 288 | 289 | 290 | expression [the] [form] content %string%: 291 | return type: string 292 | get: 293 | set {_b} to "content[;;]%expr-1%" 294 | return {_b} 295 | expression [the] button display %string%[ with (path icon %-string%|url icon %-string%)]: 296 | return type: string 297 | get: 298 | if expr-2 is set: 299 | set {_b} to "path[;;]%expr-1%[;;]%expr-2%" 300 | else if expr-3 is set: 301 | set {_b} to "url[;;]%expr-1%[;;]%expr-3%" 302 | else: 303 | set {_b} to "none[;;]%expr-1%" 304 | return {_b} 305 | 306 | expression [the] label %string%: 307 | return type: string 308 | get: 309 | set {_r} to "label[;;]%expr-1%" 310 | return {_r} 311 | 312 | expression [the] (1¦path|2¦url) icon %string%: 313 | return type: strings 314 | get: 315 | if mark is 1: 316 | set {_v::1} to "path_icon" 317 | else if mark is 2: 318 | set {_v::1} to "url_icon" 319 | set {_v::2} to expr-1 320 | return {_v::*} 321 | 322 | effect send[-| ]form %object%[ with id %-string%] to %player%: 323 | trigger: 324 | set {_F} to expr-1.build() 325 | 326 | if expr-2 is set: 327 | if {_F} is instance of SimpleForm: 328 | setListenerOnForm(expr-3, expr-1, expr-2, 1) 329 | else if {_F} is instance of ModalForm: 330 | setListenerOnForm(expr-3, expr-1, expr-2, 2) 331 | else if {_F} is instance of CustomForm: 332 | setListenerOnForm(expr-3, expr-1, expr-2, 3) 333 | FloodgateApi.getInstance().getPlayer(expr-3.getUniqueId()).sendForm({_F}) 334 | 335 | 336 | 337 | expression (1¦valid|2¦invaild|3¦closed) result handler of %object%: 338 | return type: object 339 | set: 340 | if mark is 1: 341 | expr-1.validResultHandler(change value) 342 | else if mark is 2: 343 | expr-1.closedOrInvalidResultHandler(change value) 344 | else: 345 | expr-1.closedResultHandler(change value) 346 | get: 347 | if mark is 1: 348 | return expr-1.validResultHandler() 349 | else if mark is 2: 350 | return expr-1.closedOrInvalidResultHandler() 351 | else: 352 | return expr-1.closedResultHandler() 353 | 354 | expression section handler %section%: 355 | return type: object 356 | get: 357 | set {_functions::accept} to expr-1 358 | return new proxy instance of BiConsumer using {_functions::*} 359 | 360 | expression function handler %text%: 361 | return type: object 362 | get: 363 | set {_functions::accept} to function reference expr-1 364 | return new proxy instance of BiConsumer using {_functions::*} 365 | 366 | 367 | 368 | effect [send] transfer %player% to address %string% and port %number%: 369 | trigger: 370 | set {_uuid} to expr-1.getUniqueId() 371 | set {_address} to expr-2 372 | set {_port} to expr-3 373 | FloodgateApi.getInstance().transferPlayer({_uuid}, {_address}, {_port}) 374 | 375 | 376 | function setListenerOnForm(p: player, builder: object, id: text, type: number): 377 | 378 | create section with {_proxy}, {_form}, {_r} stored in {_handler::accept}: 379 | 380 | 381 | set {_events::player} to {_p} 382 | set {_extras::form-id} to {_id} 383 | set {_extras::response} to {_r} 384 | 385 | # simple 386 | if {_type} is 1: 387 | set {_extras::form-title} to {_form}.title() 388 | set {_extras::button-id} to {_r}.clickedButtonId() 389 | set {_extras::button-name} to {_r}.clickedButton().text() 390 | call custom event "click button of form" with {_events::*} data {_extras::*} 391 | 392 | # modal 393 | else if {_type} is 2: 394 | set {_extras::button-id} to {_r}.clickedButtonId() 395 | set {_extras::button-name} to {_r}.getClickedButtonText() 396 | call custom event "click button of form" with {_events::*} data {_extras::*} 397 | 398 | # custom 399 | else: 400 | 401 | set {_extras::form-title} to {_form}.title() 402 | call custom event "submit custom form" with {_events::*} data {_extras::*} 403 | 404 | set {_proxy} to new proxy instance of BiConsumer using {_handler::*} 405 | {_builder}.validResultHandler({_proxy}) 406 | create section with {_proxy}, {_form} stored in {_handler::accept}: 407 | 408 | 409 | set {_events::player} to {_p} 410 | set {_extras::form-id} to {_id} 411 | set {_extras::form} to {_form} 412 | 413 | call custom event "close form" with {_events::*} data {_extras::*} 414 | 415 | set {_proxy} to new proxy instance of Consumer using {_handler::*} 416 | {_builder}.closedResultHandler({_proxy}) 417 | 418 | -------------------------------------------------------------------------------- /ApiGeyserUtils.sk: -------------------------------------------------------------------------------- 1 | import: 2 | org.bukkit.Bukkit 3 | org.bukkit.entity.Player 4 | 5 | org.geysermc.floodgate.api.FloodgateApi 6 | 7 | me.zimzaza4.geyserutils.spigot.api.PlayerUtils 8 | me.zimzaza4.geyserutils.common.form.element.NpcDialogueButton 9 | me.zimzaza4.geyserutils.common.form.element.NpcDialogueButton$ButtonMode 10 | me.zimzaza4.geyserutils.spigot.api.form.NpcDialogueForm 11 | 12 | java.util.function.BiConsumer 13 | java.util.function.Consumer 14 | java.util.ArrayList 15 | 16 | expression [the] dialogue [form] with title %text% and message %text% on %entity%: 17 | return type: object 18 | get: 19 | set {_F} to new NpcDialogueForm() 20 | if expr-1 is set: 21 | {_F}.title(expr-1).dialogue(expr-2).bindEntity(expr-3).hasNextForm(false).buttons(new ArrayList()) 22 | 23 | return {_F} 24 | 25 | expression [the] dialogue button display %text%: 26 | return type: object 27 | get: 28 | set {_b} to new NpcDialogueButton() 29 | {_b}.text(expr-1).mode(ButtonMode.BUTTON_MODE) 30 | set {_array} to new ArrayList() 31 | {_array}.add("no") 32 | return {_b}.commands({_array}) 33 | 34 | expression [the] skin data of %object%: 35 | return type: string 36 | get: 37 | expr-1.skinData() 38 | set: 39 | expr-1.skinData(change value) 40 | 41 | expression [the] keep open [state] of %object%: 42 | return type: boolean 43 | get: 44 | expr-1.hasNextForm() 45 | set: 46 | expr-1.hasNextForm(change value) 47 | 48 | 49 | 50 | 51 | expression [the] skin data with scale %text% and translate %text%: 52 | return type: string 53 | get: 54 | set {_s} to "{""picker_offsets"":{""scale"":[%expr-1%],""translate"":[%expr-2%]},""portrait_offsets"":{""scale"":[%expr-1%],""translate"":[%expr-2%]}}" 55 | return {_s} 56 | 57 | 58 | effect send[-| ]dialogue %object%[ with id %-string%] to %player%: 59 | trigger: 60 | if expr-2 is set: 61 | setListenerOnDialogue(expr-1, expr-2, expr-3) 62 | expr-1.send(FloodgateApi.getInstance().getPlayer(expr-3.getUniqueId())) 63 | 64 | custom event "click button of dialogue": 65 | pattern: click dialogue button 66 | event-values: player 67 | 68 | custom event "close dialogue": 69 | pattern: dialogue close 70 | event-values: player 71 | 72 | effect add %objects% to [dialogue] %object%: 73 | trigger: 74 | set {_a::*} to expr-1 75 | loop {_a::*}: 76 | expr-2.buttons().add(loop-value) 77 | 78 | effect close dialogue of %player%: 79 | trigger: 80 | NpcDialogueForm.closeForm(FloodgateApi.getInstance().getPlayer(expr-1.getUniqueId())) 81 | 82 | function setListenerOnDialogue(f: object, fid: string, p: player): 83 | create section with {_proxy}, {_form}, {_bid} stored in {_handler::accept}: 84 | 85 | set {_events::player} to {_p} 86 | set {_extras::form-id} to {_fid} 87 | set {_extras::button-id} to {_bid} 88 | call custom event "click button of dialogue" with {_events::*} data {_extras::*} 89 | 90 | 91 | set {_proxy} to new proxy instance of BiConsumer using {_handler::*} 92 | 93 | {_f}.handler({_proxy}) 94 | 95 | create section with {_proxy}, {_form} stored in {_handler::accept}: 96 | 97 | set {_events::player} to {_p} 98 | set {_extras::form-id} to {_fid} 99 | 100 | call custom event "close dialogue" with {_events::*} data {_extras::*} 101 | 102 | 103 | set {_proxy} to new proxy instance of Consumer using {_handler::*} 104 | 105 | {_f}.closeHandler({_proxy}) 106 | 107 | 108 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 zimzaza4 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Skript-Floodgate-Api 2 | 3 | Floodgate Api for Skript 4 | 5 | 6 | **How to install?** 7 | - After confirming to install all dependent plugins, put this script into plugins/Skript/scripts/ and reload it 8 | 9 | 10 | **如何安装?** 11 | - 装上Skript, [Skript-Reflect](https://github.com/TPGamesNL/skript-reflect/releases) 插件 12 | - 将该脚本放入该放的文件夹 plugins/Skript/scripts/ 13 | - 启动服务器 14 | 15 | 16 | The skript depends on plugins: 17 | - [Skript](https://github.com/SkriptLang/Skript/releases) 18 | - [Skript-Reflect](https://github.com/TPGamesNL/skript-reflect/releases) 19 | - [Floodgate](https://ci.opencollab.dev/job/GeyserMC/job/Floodgate/job/master/) 20 | 21 | 22 | 23 | [Example](https://github.com/zimzaza4/Skript-Floodgate-Form/wiki/Example) 24 | 25 | Create a Form: 26 | ``` 27 | set {_Form} to simple form with title "hello" 28 | set {_Form} to modal form with title "hello" and buttons "button1" "button2" 29 | set {_Form} to custom form with title "hello" 30 | ``` 31 | 32 | Add something to a Simple Form: 33 | ``` 34 | add button display "button" to form {_simpleform} 35 | add button display "button with url image" with url icon "url" to form {_simpleform} 36 | add button display "button with path image" with path icon "path" to form {_simpleform} 37 | add content "content" to form {_Form} 38 | ``` 39 | Send Form: 40 | ``` 41 | send form {_Form} to {_player} 42 | send form {_Form} with id "Form_id" to {_player} 43 | ``` 44 | Events: 45 | 46 | on Click Form Button: (ModalForm and SimpleForm) 47 | ``` 48 | on click form button: 49 | set {_id} to data "form-id" 50 | set {_button} to data "button-id" 51 | ``` 52 | on Submit Custom Form: (CustomForm) 53 | ``` 54 | on submit custom form: 55 | set {_id} to data "form-id" 56 | set {_input} to input component id 0 of data "response" 57 | ``` 58 | 59 | *You don't need Floodgate-Skript any more* 60 | 61 | Extra: 62 | NPC Form 63 | [GeyserUtils](https://github.com/zimzaza4/GeyserUtils 64 | --------------------------------------------------------------------------------