hope to release soon (#60)
This commit is contained in:
commit
f4d5a4695d
26 changed files with 890 additions and 124 deletions
2
.github/workflows/preview.yml
vendored
2
.github/workflows/preview.yml
vendored
|
|
@ -37,6 +37,8 @@ jobs:
|
|||
run: vercel deploy --prebuilt --token=${{ secrets.VERCEL_TOKEN }}
|
||||
id: deploy
|
||||
- name: Set deployment alias
|
||||
# only if on branch next
|
||||
if: github.ref == 'refs/heads/next'
|
||||
run: vercel alias set ${{ steps.deploy.outputs.stdout }} ${{ secrets.TEST_PREVIEW_DOMAIN }} --token=${{ secrets.VERCEL_TOKEN }}
|
||||
- uses: mshick/add-pr-comment@v2
|
||||
with:
|
||||
|
|
|
|||
14
README.MD
14
README.MD
|
|
@ -83,6 +83,20 @@ You can also drag and drop any .dat or .mca (region files) into the browser wind
|
|||
|
||||
world chunks have a *yellow* border, hostile mobs have a *red* outline, passive mobs have a *green* outline, players have a *blue* outline.
|
||||
|
||||
### Query Parameters
|
||||
|
||||
Press `Y` to set query parameters to url of your current game state.
|
||||
|
||||
- `?server=<server_address>` - Display connect screen to the server on load
|
||||
- `?username=<username>` - Set the username on load
|
||||
- `?proxy=<proxy_address>` - Set the proxy server address on load
|
||||
- `?version=<version>` - Set the version on load
|
||||
- `?reconnect=true` - Reconnect to the server on page reloads. Available in **dev mode only** and very useful on server testing.
|
||||
<!-- - `?password=<password>` - Set the password on load -->
|
||||
- `?loadSave=<save_name>` - Load the save on load with the specified folder name (not title)
|
||||
- `?singleplayer=1` - Create empty world on load. Nothing will be saved
|
||||
- `?noSave=true` - Disable auto save on unload / disconnect / export. Only manual save with `/save` command will work
|
||||
|
||||
### Notable Things that Power this Project
|
||||
|
||||
- [Mineflayer](https://github.com/PrismarineJS/mineflayer) - Handles all client-side communications with the server (including the builtin one) - forked
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@
|
|||
"stats.js": "^0.17.0",
|
||||
"tabbable": "^6.2.0",
|
||||
"title-case": "3.x",
|
||||
"ua-parser-js": "^1.0.37",
|
||||
"valtio": "^1.11.1",
|
||||
"workbox-build": "^7.0.0"
|
||||
},
|
||||
|
|
@ -83,6 +84,7 @@
|
|||
"@types/react-transition-group": "^4.4.7",
|
||||
"@types/stats.js": "^0.17.1",
|
||||
"@types/three": "0.128.0",
|
||||
"@types/ua-parser-js": "^0.7.39",
|
||||
"@xmcl/installer": "^5.1.0",
|
||||
"assert": "^2.0.0",
|
||||
"browserify-zlib": "^0.2.0",
|
||||
|
|
|
|||
28
pnpm-lock.yaml
generated
28
pnpm-lock.yaml
generated
|
|
@ -141,6 +141,9 @@ importers:
|
|||
title-case:
|
||||
specifier: 3.x
|
||||
version: 3.0.3
|
||||
ua-parser-js:
|
||||
specifier: ^1.0.37
|
||||
version: 1.0.37
|
||||
valtio:
|
||||
specifier: ^1.11.1
|
||||
version: 1.11.2(@types/react@18.2.20)(react@18.2.0)
|
||||
|
|
@ -185,6 +188,9 @@ importers:
|
|||
'@types/three':
|
||||
specifier: 0.128.0
|
||||
version: 0.128.0
|
||||
'@types/ua-parser-js':
|
||||
specifier: ^0.7.39
|
||||
version: 0.7.39
|
||||
'@xmcl/installer':
|
||||
specifier: ^5.1.0
|
||||
version: 5.1.0
|
||||
|
|
@ -235,7 +241,7 @@ importers:
|
|||
version: 1.0.0
|
||||
minecraft-inventory-gui:
|
||||
specifier: github:zardoy/minecraft-inventory-gui#next
|
||||
version: github.com/zardoy/minecraft-inventory-gui/69003692b3041d94a420a65c7d3cc1b37737e838(@types/react@18.2.20)(react@18.2.0)
|
||||
version: github.com/zardoy/minecraft-inventory-gui/e794b5d44d9cdaf58c4bf9fc5fbbc3a729f4b447(@types/react@18.2.20)(react@18.2.0)
|
||||
mineflayer:
|
||||
specifier: github:PrismarineJS/mineflayer
|
||||
version: github.com/PrismarineJS/mineflayer/cc98f1307e3ab48477d2a9ff29da4447f42b30bc
|
||||
|
|
@ -5216,6 +5222,10 @@ packages:
|
|||
/@types/trusted-types@2.0.3:
|
||||
resolution: {integrity: sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==}
|
||||
|
||||
/@types/ua-parser-js@0.7.39:
|
||||
resolution: {integrity: sha512-P/oDfpofrdtF5xw433SPALpdSchtJmY7nsJItf8h3KXqOslkbySh8zq4dSWXH2oTjRvJ5PczVEoCZPow6GicLg==}
|
||||
dev: true
|
||||
|
||||
/@types/unist@2.0.8:
|
||||
resolution: {integrity: sha512-d0XxK3YTObnWVp6rZuev3c49+j4Lo8g4L1ZRm9z5L0xpoZycUPshHgczK5gsUMaZOstjVYYi09p5gYvUtfChYw==}
|
||||
dev: true
|
||||
|
|
@ -5591,7 +5601,7 @@ packages:
|
|||
dependencies:
|
||||
change-case: 4.1.2
|
||||
colors: 1.4.0
|
||||
diamond-square: github.com/zardoy/diamond-square/789d7090748ddcae22bb89908db15ba448bdfbb0
|
||||
diamond-square: github.com/zardoy/diamond-square/915fce8e27fe8eb45464d89b9563956afa4f7687
|
||||
emit-then: 2.0.0
|
||||
event-promise: 0.0.1
|
||||
exit-hook: 2.2.1
|
||||
|
|
@ -14079,6 +14089,10 @@ packages:
|
|||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/ua-parser-js@1.0.37:
|
||||
resolution: {integrity: sha512-bhTyI94tZofjo+Dn8SN6Zv8nBDvyXTymAdM3LDI/0IboIUwTu1rEhW7v2TfiVsoYWgkQ4kOVqnI8APUFbIQIFQ==}
|
||||
dev: false
|
||||
|
||||
/ufo@1.3.1:
|
||||
resolution: {integrity: sha512-uY/99gMLIOlJPwATcMVYfqDSxUR9//AUcgZMzwfSTJPDKzA1S8mX4VLqa+fiAtveraQUBCz4FFcwVZBGbwBXIw==}
|
||||
dev: true
|
||||
|
|
@ -15168,8 +15182,8 @@ packages:
|
|||
async: 2.6.4
|
||||
dev: false
|
||||
|
||||
github.com/zardoy/diamond-square/789d7090748ddcae22bb89908db15ba448bdfbb0:
|
||||
resolution: {tarball: https://codeload.github.com/zardoy/diamond-square/tar.gz/789d7090748ddcae22bb89908db15ba448bdfbb0}
|
||||
github.com/zardoy/diamond-square/915fce8e27fe8eb45464d89b9563956afa4f7687:
|
||||
resolution: {tarball: https://codeload.github.com/zardoy/diamond-square/tar.gz/915fce8e27fe8eb45464d89b9563956afa4f7687}
|
||||
name: diamond-square
|
||||
version: 1.3.0
|
||||
dependencies:
|
||||
|
|
@ -15179,9 +15193,9 @@ packages:
|
|||
vec3: 0.1.8
|
||||
dev: false
|
||||
|
||||
github.com/zardoy/minecraft-inventory-gui/69003692b3041d94a420a65c7d3cc1b37737e838(@types/react@18.2.20)(react@18.2.0):
|
||||
resolution: {tarball: https://codeload.github.com/zardoy/minecraft-inventory-gui/tar.gz/69003692b3041d94a420a65c7d3cc1b37737e838}
|
||||
id: github.com/zardoy/minecraft-inventory-gui/69003692b3041d94a420a65c7d3cc1b37737e838
|
||||
github.com/zardoy/minecraft-inventory-gui/e794b5d44d9cdaf58c4bf9fc5fbbc3a729f4b447(@types/react@18.2.20)(react@18.2.0):
|
||||
resolution: {tarball: https://codeload.github.com/zardoy/minecraft-inventory-gui/tar.gz/e794b5d44d9cdaf58c4bf9fc5fbbc3a729f4b447}
|
||||
id: github.com/zardoy/minecraft-inventory-gui/e794b5d44d9cdaf58c4bf9fc5fbbc3a729f4b447
|
||||
name: minecraft-inventory-gui
|
||||
version: 1.0.1
|
||||
dependencies:
|
||||
|
|
|
|||
|
|
@ -179,5 +179,536 @@
|
|||
"flowering_azalea": true,
|
||||
"frogspawn": true,
|
||||
"decorated_pot": true
|
||||
},
|
||||
"colors": {
|
||||
"stone": "rgb(112, 112, 112)",
|
||||
"granite": "rgb(151, 109, 77)",
|
||||
"polished_granite": "rgb(151, 109, 77)",
|
||||
"diorite": "rgb(255, 252, 245)",
|
||||
"polished_diorite": "rgb(255, 252, 245)",
|
||||
"andesite": "rgb(112, 112, 112)",
|
||||
"polished_andesite": "rgb(112, 112, 112)",
|
||||
"grass_block": "rgb(127, 178, 56)",
|
||||
"dirt": "rgb(151, 109, 77)",
|
||||
"coarse_dirt": "rgb(151, 109, 77)",
|
||||
"podzol": "rgb(129, 86, 49)",
|
||||
"cobblestone": "rgb(112, 112, 112)",
|
||||
"oak_planks": "rgb(143, 119, 72)",
|
||||
"spruce_planks": "rgb(129, 86, 49)",
|
||||
"birch_planks": "rgb(247, 233, 163)",
|
||||
"jungle_planks": "rgb(151, 109, 77)",
|
||||
"acacia_planks": "rgb(216, 127, 51)",
|
||||
"cherry_planks": "rgb(209, 177, 161)",
|
||||
"dark_oak_planks": "rgb(102, 76, 51)",
|
||||
"mangrove_planks": "rgb(153, 51, 51)",
|
||||
"bamboo_planks": "rgb(229, 229, 51)",
|
||||
"bamboo_mosaic": "rgb(229, 229, 51)",
|
||||
"oak_sapling": "rgb(0, 124, 0)",
|
||||
"spruce_sapling": "rgb(0, 124, 0)",
|
||||
"birch_sapling": "rgb(0, 124, 0)",
|
||||
"jungle_sapling": "rgb(0, 124, 0)",
|
||||
"acacia_sapling": "rgb(0, 124, 0)",
|
||||
"cherry_sapling": "rgb(242, 127, 165)",
|
||||
"dark_oak_sapling": "rgb(0, 124, 0)",
|
||||
"mangrove_propagule": "rgb(0, 124, 0)",
|
||||
"bedrock": "rgb(112, 112, 112)",
|
||||
"water": "rgb(64, 64, 255)",
|
||||
"lava": "rgb(255, 0, 0)",
|
||||
"sand": "rgb(247, 233, 163)",
|
||||
"suspicious_sand": "rgb(247, 233, 163)",
|
||||
"red_sand": "rgb(216, 127, 51)",
|
||||
"gravel": "rgb(112, 112, 112)",
|
||||
"suspicious_gravel": "rgb(112, 112, 112)",
|
||||
"gold_ore": "rgb(112, 112, 112)",
|
||||
"deepslate_gold_ore": "rgb(100, 100, 100)",
|
||||
"iron_ore": "rgb(112, 112, 112)",
|
||||
"deepslate_iron_ore": "rgb(100, 100, 100)",
|
||||
"coal_ore": "rgb(112, 112, 112)",
|
||||
"deepslate_coal_ore": "rgb(100, 100, 100)",
|
||||
"nether_gold_ore": "rgb(112, 2, 0)",
|
||||
"mangrove_roots": "rgb(129, 86, 49)",
|
||||
"muddy_mangrove_roots": "rgb(129, 86, 49)",
|
||||
"oak_wood": "rgb(143, 119, 72)",
|
||||
"spruce_wood": "rgb(129, 86, 49)",
|
||||
"birch_wood": "rgb(247, 233, 163)",
|
||||
"jungle_wood": "rgb(151, 109, 77)",
|
||||
"acacia_wood": "rgb(76, 76, 76)",
|
||||
"cherry_wood": "rgb(57, 41, 35)",
|
||||
"dark_oak_wood": "rgb(102, 76, 51)",
|
||||
"mangrove_wood": "rgb(153, 51, 51)",
|
||||
"stripped_oak_wood": "rgb(143, 119, 72)",
|
||||
"stripped_spruce_wood": "rgb(129, 86, 49)",
|
||||
"stripped_birch_wood": "rgb(247, 233, 163)",
|
||||
"stripped_jungle_wood": "rgb(151, 109, 77)",
|
||||
"stripped_acacia_wood": "rgb(216, 127, 51)",
|
||||
"stripped_cherry_wood": "rgb(160, 77, 78)",
|
||||
"stripped_dark_oak_wood": "rgb(102, 76, 51)",
|
||||
"oak_leaves": "rgb(0, 124, 0)",
|
||||
"spruce_leaves": "rgb(0, 124, 0)",
|
||||
"birch_leaves": "rgb(0, 124, 0)",
|
||||
"jungle_leaves": "rgb(0, 124, 0)",
|
||||
"acacia_leaves": "rgb(0, 124, 0)",
|
||||
"cherry_leaves": "rgb(242, 127, 165)",
|
||||
"dark_oak_leaves": "rgb(0, 124, 0)",
|
||||
"mangrove_leaves": "rgb(0, 124, 0)",
|
||||
"azalea_leaves": "rgb(0, 124, 0)",
|
||||
"flowering_azalea_leaves": "rgb(0, 124, 0)",
|
||||
"sponge": "rgb(229, 229, 51)",
|
||||
"wet_sponge": "rgb(229, 229, 51)",
|
||||
"lapis_ore": "rgb(112, 112, 112)",
|
||||
"deepslate_lapis_ore": "rgb(100, 100, 100)",
|
||||
"lapis_block": "rgb(74, 128, 255)",
|
||||
"dispenser": "rgb(112, 112, 112)",
|
||||
"sandstone": "rgb(247, 233, 163)",
|
||||
"chiseled_sandstone": "rgb(247, 233, 163)",
|
||||
"cut_sandstone": "rgb(247, 233, 163)",
|
||||
"note_block": "rgb(143, 119, 72)",
|
||||
"sticky_piston": "rgb(112, 112, 112)",
|
||||
"cobweb": "rgb(199, 199, 199)",
|
||||
"grass": "rgb(0, 124, 0)",
|
||||
"fern": "rgb(0, 124, 0)",
|
||||
"dead_bush": "rgb(143, 119, 72)",
|
||||
"seagrass": "rgb(64, 64, 255)",
|
||||
"tall_seagrass": "rgb(64, 64, 255)",
|
||||
"piston": "rgb(112, 112, 112)",
|
||||
"piston_head": "rgb(112, 112, 112)",
|
||||
"white_wool": "rgb(255, 255, 255)",
|
||||
"orange_wool": "rgb(216, 127, 51)",
|
||||
"magenta_wool": "rgb(178, 76, 216)",
|
||||
"light_blue_wool": "rgb(102, 153, 216)",
|
||||
"yellow_wool": "rgb(229, 229, 51)",
|
||||
"lime_wool": "rgb(127, 204, 25)",
|
||||
"pink_wool": "rgb(242, 127, 165)",
|
||||
"gray_wool": "rgb(76, 76, 76)",
|
||||
"light_gray_wool": "rgb(153, 153, 153)",
|
||||
"cyan_wool": "rgb(76, 127, 153)",
|
||||
"purple_wool": "rgb(127, 63, 178)",
|
||||
"blue_wool": "rgb(51, 76, 178)",
|
||||
"brown_wool": "rgb(102, 76, 51)",
|
||||
"green_wool": "rgb(102, 127, 51)",
|
||||
"red_wool": "rgb(153, 51, 51)",
|
||||
"black_wool": "rgb(25, 25, 25)",
|
||||
"moving_piston": "rgb(112, 112, 112)",
|
||||
"dandelion": "rgb(0, 124, 0)",
|
||||
"torchflower": "rgb(0, 124, 0)",
|
||||
"poppy": "rgb(0, 124, 0)",
|
||||
"blue_orchid": "rgb(0, 124, 0)",
|
||||
"allium": "rgb(0, 124, 0)",
|
||||
"azure_bluet": "rgb(0, 124, 0)",
|
||||
"red_tulip": "rgb(0, 124, 0)",
|
||||
"orange_tulip": "rgb(0, 124, 0)",
|
||||
"white_tulip": "rgb(0, 124, 0)",
|
||||
"pink_tulip": "rgb(0, 124, 0)",
|
||||
"oxeye_daisy": "rgb(0, 124, 0)",
|
||||
"cornflower": "rgb(0, 124, 0)",
|
||||
"wither_rose": "rgb(0, 124, 0)",
|
||||
"lily_of_the_valley": "rgb(0, 124, 0)",
|
||||
"brown_mushroom": "rgb(102, 76, 51)",
|
||||
"red_mushroom": "rgb(153, 51, 51)",
|
||||
"gold_block": "rgb(250, 238, 77)",
|
||||
"iron_block": "rgb(167, 167, 167)",
|
||||
"bricks": "rgb(153, 51, 51)",
|
||||
"tnt": "rgb(255, 0, 0)",
|
||||
"bookshelf": "rgb(143, 119, 72)",
|
||||
"chiseled_bookshelf": "rgb(143, 119, 72)",
|
||||
"mossy_cobblestone": "rgb(112, 112, 112)",
|
||||
"obsidian": "rgb(25, 25, 25)",
|
||||
"fire": "rgb(255, 0, 0)",
|
||||
"soul_fire": "rgb(102, 153, 216)",
|
||||
"spawner": "rgb(112, 112, 112)",
|
||||
"chest": "rgb(143, 119, 72)",
|
||||
"diamond_ore": "rgb(112, 112, 112)",
|
||||
"deepslate_diamond_ore": "rgb(100, 100, 100)",
|
||||
"diamond_block": "rgb(92, 219, 213)",
|
||||
"crafting_table": "rgb(143, 119, 72)",
|
||||
"wheat": "rgb(0, 124, 0)",
|
||||
"farmland": "rgb(151, 109, 77)",
|
||||
"furnace": "rgb(112, 112, 112)",
|
||||
"oak_sign": "rgb(143, 119, 72)",
|
||||
"birch_sign": "rgb(247, 233, 163)",
|
||||
"acacia_sign": "rgb(216, 127, 51)",
|
||||
"oak_wall_sign": "rgb(143, 119, 72)",
|
||||
"birch_wall_sign": "rgb(247, 233, 163)",
|
||||
"acacia_wall_sign": "rgb(216, 127, 51)",
|
||||
"birch_hanging_sign": "rgb(247, 233, 163)",
|
||||
"acacia_hanging_sign": "rgb(216, 127, 51)",
|
||||
"cherry_hanging_sign": "rgb(160, 77, 78)",
|
||||
"crimson_hanging_sign": "rgb(148, 63, 97)",
|
||||
"warped_hanging_sign": "rgb(58, 142, 140)",
|
||||
"bamboo_hanging_sign": "rgb(229, 229, 51)",
|
||||
"spruce_wall_hanging_sign": "rgb(143, 119, 72)",
|
||||
"birch_wall_hanging_sign": "rgb(247, 233, 163)",
|
||||
"acacia_wall_hanging_sign": "rgb(216, 127, 51)",
|
||||
"cherry_wall_hanging_sign": "rgb(160, 77, 78)",
|
||||
"crimson_wall_hanging_sign": "rgb(148, 63, 97)",
|
||||
"warped_wall_hanging_sign": "rgb(58, 142, 140)",
|
||||
"bamboo_wall_hanging_sign": "rgb(229, 229, 51)",
|
||||
"stone_pressure_plate": "rgb(112, 112, 112)",
|
||||
"iron_door": "rgb(167, 167, 167)",
|
||||
"redstone_ore": "rgb(112, 112, 112)",
|
||||
"deepslate_redstone_ore": "rgb(100, 100, 100)",
|
||||
"snow": "rgb(255, 255, 255)",
|
||||
"ice": "rgb(160, 160, 255)",
|
||||
"snow_block": "rgb(255, 255, 255)",
|
||||
"cactus": "rgb(0, 124, 0)",
|
||||
"clay": "rgb(164, 168, 184)",
|
||||
"sugar_cane": "rgb(0, 124, 0)",
|
||||
"jukebox": "rgb(151, 109, 77)",
|
||||
"pumpkin": "rgb(216, 127, 51)",
|
||||
"netherrack": "rgb(112, 2, 0)",
|
||||
"soul_sand": "rgb(102, 76, 51)",
|
||||
"soul_soil": "rgb(102, 76, 51)",
|
||||
"basalt": "rgb(25, 25, 25)",
|
||||
"polished_basalt": "rgb(25, 25, 25)",
|
||||
"glowstone": "rgb(247, 233, 163)",
|
||||
"carved_pumpkin": "rgb(216, 127, 51)",
|
||||
"jack_o_lantern": "rgb(216, 127, 51)",
|
||||
"oak_trapdoor": "rgb(143, 119, 72)",
|
||||
"spruce_trapdoor": "rgb(129, 86, 49)",
|
||||
"birch_trapdoor": "rgb(247, 233, 163)",
|
||||
"jungle_trapdoor": "rgb(151, 109, 77)",
|
||||
"acacia_trapdoor": "rgb(216, 127, 51)",
|
||||
"cherry_trapdoor": "rgb(209, 177, 161)",
|
||||
"dark_oak_trapdoor": "rgb(102, 76, 51)",
|
||||
"mangrove_trapdoor": "rgb(153, 51, 51)",
|
||||
"bamboo_trapdoor": "rgb(229, 229, 51)",
|
||||
"stone_bricks": "rgb(112, 112, 112)",
|
||||
"mossy_stone_bricks": "rgb(112, 112, 112)",
|
||||
"cracked_stone_bricks": "rgb(112, 112, 112)",
|
||||
"chiseled_stone_bricks": "rgb(112, 112, 112)",
|
||||
"mud_bricks": "rgb(135, 107, 98)",
|
||||
"infested_stone": "rgb(164, 168, 184)",
|
||||
"infested_cobblestone": "rgb(164, 168, 184)",
|
||||
"infested_stone_bricks": "rgb(164, 168, 184)",
|
||||
"infested_mossy_stone_bricks": "rgb(164, 168, 184)",
|
||||
"infested_cracked_stone_bricks": "rgb(164, 168, 184)",
|
||||
"infested_chiseled_stone_bricks": "rgb(164, 168, 184)",
|
||||
"brown_mushroom_block": "rgb(151, 109, 77)",
|
||||
"red_mushroom_block": "rgb(153, 51, 51)",
|
||||
"mushroom_stem": "rgb(199, 199, 199)",
|
||||
"melon": "rgb(127, 204, 25)",
|
||||
"attached_pumpkin_stem": "rgb(0, 124, 0)",
|
||||
"attached_melon_stem": "rgb(0, 124, 0)",
|
||||
"pumpkin_stem": "rgb(0, 124, 0)",
|
||||
"melon_stem": "rgb(0, 124, 0)",
|
||||
"vine": "rgb(0, 124, 0)",
|
||||
"glow_lichen": "rgb(127, 167, 150)",
|
||||
"mycelium": "rgb(127, 63, 178)",
|
||||
"lily_pad": "rgb(0, 124, 0)",
|
||||
"nether_bricks": "rgb(112, 2, 0)",
|
||||
"nether_brick_fence": "rgb(112, 2, 0)",
|
||||
"nether_wart": "rgb(153, 51, 51)",
|
||||
"enchanting_table": "rgb(153, 51, 51)",
|
||||
"brewing_stand": "rgb(167, 167, 167)",
|
||||
"cauldron": "rgb(112, 112, 112)",
|
||||
"end_portal": "rgb(25, 25, 25)",
|
||||
"end_portal_frame": "rgb(102, 127, 51)",
|
||||
"end_stone": "rgb(247, 233, 163)",
|
||||
"dragon_egg": "rgb(25, 25, 25)",
|
||||
"cocoa": "rgb(0, 124, 0)",
|
||||
"emerald_ore": "rgb(112, 112, 112)",
|
||||
"deepslate_emerald_ore": "rgb(100, 100, 100)",
|
||||
"ender_chest": "rgb(112, 112, 112)",
|
||||
"emerald_block": "rgb(0, 217, 58)",
|
||||
"command_block": "rgb(102, 76, 51)",
|
||||
"beacon": "rgb(92, 219, 213)",
|
||||
"carrots": "rgb(0, 124, 0)",
|
||||
"potatoes": "rgb(0, 124, 0)",
|
||||
"anvil": "rgb(167, 167, 167)",
|
||||
"chipped_anvil": "rgb(167, 167, 167)",
|
||||
"damaged_anvil": "rgb(167, 167, 167)",
|
||||
"trapped_chest": "rgb(143, 119, 72)",
|
||||
"light_weighted_pressure_plate": "rgb(250, 238, 77)",
|
||||
"heavy_weighted_pressure_plate": "rgb(167, 167, 167)",
|
||||
"daylight_detector": "rgb(143, 119, 72)",
|
||||
"redstone_block": "rgb(255, 0, 0)",
|
||||
"nether_quartz_ore": "rgb(112, 2, 0)",
|
||||
"hopper": "rgb(112, 112, 112)",
|
||||
"quartz_block": "rgb(255, 252, 245)",
|
||||
"chiseled_quartz_block": "rgb(255, 252, 245)",
|
||||
"quartz_pillar": "rgb(255, 252, 245)",
|
||||
"dropper": "rgb(112, 112, 112)",
|
||||
"white_terracotta": "rgb(209, 177, 161)",
|
||||
"orange_terracotta": "rgb(159, 82, 36)",
|
||||
"magenta_terracotta": "rgb(149, 87, 108)",
|
||||
"light_blue_terracotta": "rgb(112, 108, 138)",
|
||||
"yellow_terracotta": "rgb(186, 133, 36)",
|
||||
"lime_terracotta": "rgb(103, 117, 53)",
|
||||
"pink_terracotta": "rgb(160, 77, 78)",
|
||||
"gray_terracotta": "rgb(57, 41, 35)",
|
||||
"light_gray_terracotta": "rgb(135, 107, 98)",
|
||||
"cyan_terracotta": "rgb(87, 92, 92)",
|
||||
"purple_terracotta": "rgb(122, 73, 88)",
|
||||
"blue_terracotta": "rgb(76, 62, 92)",
|
||||
"brown_terracotta": "rgb(76, 50, 35)",
|
||||
"green_terracotta": "rgb(76, 82, 42)",
|
||||
"red_terracotta": "rgb(142, 60, 46)",
|
||||
"black_terracotta": "rgb(37, 22, 16)",
|
||||
"slime_block": "rgb(127, 178, 56)",
|
||||
"iron_trapdoor": "rgb(167, 167, 167)",
|
||||
"prismarine": "rgb(76, 127, 153)",
|
||||
"prismarine_bricks": "rgb(92, 219, 213)",
|
||||
"dark_prismarine": "rgb(92, 219, 213)",
|
||||
"prismarine_slab": "rgb(76, 127, 153)",
|
||||
"prismarine_brick_slab": "rgb(92, 219, 213)",
|
||||
"dark_prismarine_slab": "rgb(92, 219, 213)",
|
||||
"sea_lantern": "rgb(255, 252, 245)",
|
||||
"hay_block": "rgb(229, 229, 51)",
|
||||
"white_carpet": "rgb(255, 255, 255)",
|
||||
"orange_carpet": "rgb(216, 127, 51)",
|
||||
"magenta_carpet": "rgb(178, 76, 216)",
|
||||
"light_blue_carpet": "rgb(102, 153, 216)",
|
||||
"yellow_carpet": "rgb(229, 229, 51)",
|
||||
"lime_carpet": "rgb(127, 204, 25)",
|
||||
"pink_carpet": "rgb(242, 127, 165)",
|
||||
"gray_carpet": "rgb(76, 76, 76)",
|
||||
"light_gray_carpet": "rgb(153, 153, 153)",
|
||||
"cyan_carpet": "rgb(76, 127, 153)",
|
||||
"purple_carpet": "rgb(127, 63, 178)",
|
||||
"blue_carpet": "rgb(51, 76, 178)",
|
||||
"brown_carpet": "rgb(102, 76, 51)",
|
||||
"green_carpet": "rgb(102, 127, 51)",
|
||||
"red_carpet": "rgb(153, 51, 51)",
|
||||
"black_carpet": "rgb(25, 25, 25)",
|
||||
"terracotta": "rgb(216, 127, 51)",
|
||||
"coal_block": "rgb(25, 25, 25)",
|
||||
"packed_ice": "rgb(160, 160, 255)",
|
||||
"sunflower": "rgb(0, 124, 0)",
|
||||
"lilac": "rgb(0, 124, 0)",
|
||||
"rose_bush": "rgb(0, 124, 0)",
|
||||
"peony": "rgb(0, 124, 0)",
|
||||
"tall_grass": "rgb(0, 124, 0)",
|
||||
"large_fern": "rgb(0, 124, 0)",
|
||||
"white_banner": "rgb(143, 119, 72)",
|
||||
"orange_banner": "rgb(143, 119, 72)",
|
||||
"magenta_banner": "rgb(143, 119, 72)",
|
||||
"light_blue_banner": "rgb(143, 119, 72)",
|
||||
"yellow_banner": "rgb(143, 119, 72)",
|
||||
"lime_banner": "rgb(143, 119, 72)",
|
||||
"pink_banner": "rgb(143, 119, 72)",
|
||||
"gray_banner": "rgb(143, 119, 72)",
|
||||
"light_gray_banner": "rgb(143, 119, 72)",
|
||||
"cyan_banner": "rgb(143, 119, 72)",
|
||||
"purple_banner": "rgb(143, 119, 72)",
|
||||
"blue_banner": "rgb(143, 119, 72)",
|
||||
"brown_banner": "rgb(143, 119, 72)",
|
||||
"green_banner": "rgb(143, 119, 72)",
|
||||
"red_banner": "rgb(143, 119, 72)",
|
||||
"black_banner": "rgb(143, 119, 72)",
|
||||
"white_wall_banner": "rgb(143, 119, 72)",
|
||||
"orange_wall_banner": "rgb(143, 119, 72)",
|
||||
"magenta_wall_banner": "rgb(143, 119, 72)",
|
||||
"light_blue_wall_banner": "rgb(143, 119, 72)",
|
||||
"yellow_wall_banner": "rgb(143, 119, 72)",
|
||||
"lime_wall_banner": "rgb(143, 119, 72)",
|
||||
"pink_wall_banner": "rgb(143, 119, 72)",
|
||||
"gray_wall_banner": "rgb(143, 119, 72)",
|
||||
"light_gray_wall_banner": "rgb(143, 119, 72)",
|
||||
"cyan_wall_banner": "rgb(143, 119, 72)",
|
||||
"purple_wall_banner": "rgb(143, 119, 72)",
|
||||
"blue_wall_banner": "rgb(143, 119, 72)",
|
||||
"brown_wall_banner": "rgb(143, 119, 72)",
|
||||
"green_wall_banner": "rgb(143, 119, 72)",
|
||||
"red_wall_banner": "rgb(143, 119, 72)",
|
||||
"black_wall_banner": "rgb(143, 119, 72)",
|
||||
"red_sandstone": "rgb(216, 127, 51)",
|
||||
"chiseled_red_sandstone": "rgb(216, 127, 51)",
|
||||
"cut_red_sandstone": "rgb(216, 127, 51)",
|
||||
"oak_slab": "rgb(143, 119, 72)",
|
||||
"spruce_slab": "rgb(129, 86, 49)",
|
||||
"birch_slab": "rgb(247, 233, 163)",
|
||||
"jungle_slab": "rgb(151, 109, 77)",
|
||||
"acacia_slab": "rgb(216, 127, 51)",
|
||||
"cherry_slab": "rgb(209, 177, 161)",
|
||||
"dark_oak_slab": "rgb(102, 76, 51)",
|
||||
"mangrove_slab": "rgb(153, 51, 51)",
|
||||
"bamboo_slab": "rgb(229, 229, 51)",
|
||||
"bamboo_mosaic_slab": "rgb(229, 229, 51)",
|
||||
"stone_slab": "rgb(112, 112, 112)",
|
||||
"smooth_stone_slab": "rgb(112, 112, 112)",
|
||||
"sandstone_slab": "rgb(247, 233, 163)",
|
||||
"cut_sandstone_slab": "rgb(247, 233, 163)",
|
||||
"petrified_oak_slab": "rgb(143, 119, 72)",
|
||||
"cobblestone_slab": "rgb(112, 112, 112)",
|
||||
"brick_slab": "rgb(153, 51, 51)",
|
||||
"stone_brick_slab": "rgb(112, 112, 112)",
|
||||
"mud_brick_slab": "rgb(135, 107, 98)",
|
||||
"nether_brick_slab": "rgb(112, 2, 0)",
|
||||
"quartz_slab": "rgb(255, 252, 245)",
|
||||
"red_sandstone_slab": "rgb(216, 127, 51)",
|
||||
"cut_red_sandstone_slab": "rgb(216, 127, 51)",
|
||||
"purpur_slab": "rgb(178, 76, 216)",
|
||||
"smooth_stone": "rgb(112, 112, 112)",
|
||||
"smooth_sandstone": "rgb(247, 233, 163)",
|
||||
"smooth_quartz": "rgb(255, 252, 245)",
|
||||
"smooth_red_sandstone": "rgb(216, 127, 51)",
|
||||
"chorus_plant": "rgb(127, 63, 178)",
|
||||
"chorus_flower": "rgb(127, 63, 178)",
|
||||
"purpur_block": "rgb(178, 76, 216)",
|
||||
"purpur_pillar": "rgb(178, 76, 216)",
|
||||
"end_stone_bricks": "rgb(247, 233, 163)",
|
||||
"torchflower_crop": "rgb(0, 124, 0)",
|
||||
"pitcher_crop": "rgb(0, 124, 0)",
|
||||
"pitcher_plant": "rgb(0, 124, 0)",
|
||||
"beetroots": "rgb(0, 124, 0)",
|
||||
"dirt_path": "rgb(151, 109, 77)",
|
||||
"end_gateway": "rgb(25, 25, 25)",
|
||||
"repeating_command_block": "rgb(127, 63, 178)",
|
||||
"chain_command_block": "rgb(102, 127, 51)",
|
||||
"frosted_ice": "rgb(160, 160, 255)",
|
||||
"magma_block": "rgb(112, 2, 0)",
|
||||
"nether_wart_block": "rgb(153, 51, 51)",
|
||||
"red_nether_bricks": "rgb(112, 2, 0)",
|
||||
"bone_block": "rgb(247, 233, 163)",
|
||||
"observer": "rgb(112, 112, 112)",
|
||||
"kelp": "rgb(64, 64, 255)",
|
||||
"kelp_plant": "rgb(64, 64, 255)",
|
||||
"dried_kelp_block": "rgb(102, 127, 51)",
|
||||
"turtle_egg": "rgb(247, 233, 163)",
|
||||
"sniffer_egg": "rgb(153, 51, 51)",
|
||||
"dead_tube_coral_block": "rgb(76, 76, 76)",
|
||||
"dead_brain_coral_block": "rgb(76, 76, 76)",
|
||||
"dead_bubble_coral_block": "rgb(76, 76, 76)",
|
||||
"dead_fire_coral_block": "rgb(76, 76, 76)",
|
||||
"dead_horn_coral_block": "rgb(76, 76, 76)",
|
||||
"tube_coral_block": "rgb(51, 76, 178)",
|
||||
"brain_coral_block": "rgb(242, 127, 165)",
|
||||
"bubble_coral_block": "rgb(127, 63, 178)",
|
||||
"fire_coral_block": "rgb(153, 51, 51)",
|
||||
"horn_coral_block": "rgb(229, 229, 51)",
|
||||
"dead_tube_coral": "rgb(76, 76, 76)",
|
||||
"dead_brain_coral": "rgb(76, 76, 76)",
|
||||
"dead_bubble_coral": "rgb(76, 76, 76)",
|
||||
"dead_fire_coral": "rgb(76, 76, 76)",
|
||||
"dead_horn_coral": "rgb(76, 76, 76)",
|
||||
"tube_coral": "rgb(51, 76, 178)",
|
||||
"brain_coral": "rgb(242, 127, 165)",
|
||||
"bubble_coral": "rgb(127, 63, 178)",
|
||||
"fire_coral": "rgb(153, 51, 51)",
|
||||
"horn_coral": "rgb(229, 229, 51)",
|
||||
"dead_tube_coral_fan": "rgb(76, 76, 76)",
|
||||
"dead_brain_coral_fan": "rgb(76, 76, 76)",
|
||||
"dead_bubble_coral_fan": "rgb(76, 76, 76)",
|
||||
"dead_fire_coral_fan": "rgb(76, 76, 76)",
|
||||
"dead_horn_coral_fan": "rgb(76, 76, 76)",
|
||||
"tube_coral_fan": "rgb(51, 76, 178)",
|
||||
"brain_coral_fan": "rgb(242, 127, 165)",
|
||||
"bubble_coral_fan": "rgb(127, 63, 178)",
|
||||
"fire_coral_fan": "rgb(153, 51, 51)",
|
||||
"horn_coral_fan": "rgb(229, 229, 51)",
|
||||
"dead_tube_coral_wall_fan": "rgb(76, 76, 76)",
|
||||
"dead_brain_coral_wall_fan": "rgb(76, 76, 76)",
|
||||
"dead_bubble_coral_wall_fan": "rgb(76, 76, 76)",
|
||||
"dead_fire_coral_wall_fan": "rgb(76, 76, 76)",
|
||||
"dead_horn_coral_wall_fan": "rgb(76, 76, 76)",
|
||||
"tube_coral_wall_fan": "rgb(51, 76, 178)",
|
||||
"brain_coral_wall_fan": "rgb(242, 127, 165)",
|
||||
"bubble_coral_wall_fan": "rgb(127, 63, 178)",
|
||||
"fire_coral_wall_fan": "rgb(153, 51, 51)",
|
||||
"horn_coral_wall_fan": "rgb(229, 229, 51)",
|
||||
"sea_pickle": "rgb(102, 127, 51)",
|
||||
"blue_ice": "rgb(160, 160, 255)",
|
||||
"conduit": "rgb(92, 219, 213)",
|
||||
"bamboo_sapling": "rgb(143, 119, 72)",
|
||||
"bamboo": "rgb(0, 124, 0)",
|
||||
"bubble_column": "rgb(64, 64, 255)",
|
||||
"scaffolding": "rgb(247, 233, 163)",
|
||||
"loom": "rgb(143, 119, 72)",
|
||||
"barrel": "rgb(143, 119, 72)",
|
||||
"smoker": "rgb(112, 112, 112)",
|
||||
"blast_furnace": "rgb(112, 112, 112)",
|
||||
"cartography_table": "rgb(143, 119, 72)",
|
||||
"fletching_table": "rgb(143, 119, 72)",
|
||||
"grindstone": "rgb(167, 167, 167)",
|
||||
"lectern": "rgb(143, 119, 72)",
|
||||
"smithing_table": "rgb(143, 119, 72)",
|
||||
"stonecutter": "rgb(112, 112, 112)",
|
||||
"bell": "rgb(250, 238, 77)",
|
||||
"lantern": "rgb(167, 167, 167)",
|
||||
"soul_lantern": "rgb(167, 167, 167)",
|
||||
"campfire": "rgb(129, 86, 49)",
|
||||
"soul_campfire": "rgb(129, 86, 49)",
|
||||
"sweet_berry_bush": "rgb(0, 124, 0)",
|
||||
"warped_hyphae": "rgb(86, 44, 62)",
|
||||
"stripped_warped_hyphae": "rgb(86, 44, 62)",
|
||||
"warped_nylium": "rgb(22, 126, 134)",
|
||||
"warped_fungus": "rgb(76, 127, 153)",
|
||||
"warped_wart_block": "rgb(20, 180, 133)",
|
||||
"warped_roots": "rgb(76, 127, 153)",
|
||||
"nether_sprouts": "rgb(76, 127, 153)",
|
||||
"crimson_hyphae": "rgb(92, 25, 29)",
|
||||
"stripped_crimson_hyphae": "rgb(92, 25, 29)",
|
||||
"crimson_nylium": "rgb(189, 48, 49)",
|
||||
"crimson_fungus": "rgb(112, 2, 0)",
|
||||
"shroomlight": "rgb(153, 51, 51)",
|
||||
"weeping_vines": "rgb(112, 2, 0)",
|
||||
"weeping_vines_plant": "rgb(112, 2, 0)",
|
||||
"twisting_vines": "rgb(76, 127, 153)",
|
||||
"twisting_vines_plant": "rgb(76, 127, 153)",
|
||||
"crimson_roots": "rgb(112, 2, 0)",
|
||||
"crimson_planks": "rgb(148, 63, 97)",
|
||||
"warped_planks": "rgb(58, 142, 140)",
|
||||
"structure_block": "rgb(153, 153, 153)",
|
||||
"jigsaw": "rgb(153, 153, 153)",
|
||||
"composter": "rgb(143, 119, 72)",
|
||||
"target": "rgb(255, 252, 245)",
|
||||
"bee_nest": "rgb(229, 229, 51)",
|
||||
"beehive": "rgb(143, 119, 72)",
|
||||
"honey_block": "rgb(216, 127, 51)",
|
||||
"honeycomb_block": "rgb(216, 127, 51)",
|
||||
"netherite_block": "rgb(25, 25, 25)",
|
||||
"ancient_debris": "rgb(25, 25, 25)",
|
||||
"crying_obsidian": "rgb(25, 25, 25)",
|
||||
"respawn_anchor": "rgb(25, 25, 25)",
|
||||
"lodestone": "rgb(167, 167, 167)",
|
||||
"blackstone": "rgb(25, 25, 25)",
|
||||
"polished_blackstone_pressure_plate": "rgb(25, 25, 25)",
|
||||
"chiseled_nether_bricks": "rgb(112, 2, 0)",
|
||||
"cracked_nether_bricks": "rgb(112, 2, 0)",
|
||||
"amethyst_block": "rgb(127, 63, 178)",
|
||||
"budding_amethyst": "rgb(127, 63, 178)",
|
||||
"amethyst_cluster": "rgb(127, 63, 178)",
|
||||
"tuff": "rgb(57, 41, 35)",
|
||||
"calcite": "rgb(209, 177, 161)",
|
||||
"tinted_glass": "rgb(76, 76, 76)",
|
||||
"powder_snow": "rgb(255, 255, 255)",
|
||||
"sculk_sensor": "rgb(76, 127, 153)",
|
||||
"sculk": "rgb(25, 25, 25)",
|
||||
"sculk_vein": "rgb(25, 25, 25)",
|
||||
"sculk_catalyst": "rgb(25, 25, 25)",
|
||||
"sculk_shrieker": "rgb(25, 25, 25)",
|
||||
"oxidized_copper": "rgb(22, 126, 134)",
|
||||
"weathered_copper": "rgb(58, 142, 140)",
|
||||
"exposed_copper": "rgb(135, 107, 98)",
|
||||
"copper_block": "rgb(216, 127, 51)",
|
||||
"deepslate_copper_ore": "rgb(100, 100, 100)",
|
||||
"lightning_rod": "rgb(216, 127, 51)",
|
||||
"pointed_dripstone": "rgb(76, 50, 35)",
|
||||
"dripstone_block": "rgb(76, 50, 35)",
|
||||
"cave_vines": "rgb(0, 124, 0)",
|
||||
"cave_vines_plant": "rgb(0, 124, 0)",
|
||||
"spore_blossom": "rgb(0, 124, 0)",
|
||||
"azalea": "rgb(0, 124, 0)",
|
||||
"flowering_azalea": "rgb(0, 124, 0)",
|
||||
"moss_carpet": "rgb(102, 127, 51)",
|
||||
"pink_petals": "rgb(0, 124, 0)",
|
||||
"moss_block": "rgb(102, 127, 51)",
|
||||
"big_dripleaf": "rgb(0, 124, 0)",
|
||||
"big_dripleaf_stem": "rgb(0, 124, 0)",
|
||||
"small_dripleaf": "rgb(0, 124, 0)",
|
||||
"hanging_roots": "rgb(151, 109, 77)",
|
||||
"rooted_dirt": "rgb(151, 109, 77)",
|
||||
"mud": "rgb(87, 92, 92)",
|
||||
"deepslate": "rgb(100, 100, 100)",
|
||||
"infested_deepslate": "rgb(100, 100, 100)",
|
||||
"raw_iron_block": "rgb(216, 175, 147)",
|
||||
"raw_copper_block": "rgb(216, 127, 51)",
|
||||
"raw_gold_block": "rgb(250, 238, 77)",
|
||||
"ochre_froglight": "rgb(247, 233, 163)",
|
||||
"verdant_froglight": "rgb(127, 167, 150)",
|
||||
"pearlescent_froglight": "rgb(242, 127, 165)",
|
||||
"frogspawn": "rgb(64, 64, 255)",
|
||||
"reinforced_deepslate": "rgb(100, 100, 100)",
|
||||
"decorated_pot": "rgb(142, 60, 46)"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
34
src/GlobalSearchInput.tsx
Normal file
34
src/GlobalSearchInput.tsx
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import { useSnapshot } from 'valtio'
|
||||
import { miscUiState } from './globalState'
|
||||
import Input from './react/Input'
|
||||
|
||||
function InnerSearch () {
|
||||
const { currentTouch } = useSnapshot(miscUiState)
|
||||
|
||||
return <div style={{
|
||||
position: 'fixed',
|
||||
top: 5,
|
||||
left: 0,
|
||||
right: 0,
|
||||
margin: 'auto',
|
||||
zIndex: 11,
|
||||
width: 'min-content',
|
||||
}}>
|
||||
<Input
|
||||
autoFocus={currentTouch === false}
|
||||
width={50}
|
||||
placeholder='Search...'
|
||||
defaultValue=""
|
||||
onChange={({ target: { value } }) => {
|
||||
customEvents.emit('search', value)
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
|
||||
// todo remove component as its not possible to reuse this component atm
|
||||
export default () => {
|
||||
const { displaySearchInput } = useSnapshot(miscUiState)
|
||||
|
||||
return displaySearchInput ? <InnerSearch /> : null
|
||||
}
|
||||
|
|
@ -105,3 +105,15 @@ export const formatMessage = (message: MessageInput) => {
|
|||
|
||||
return msglist
|
||||
}
|
||||
|
||||
const blockToItemRemaps = {
|
||||
water: 'water_bucket',
|
||||
lava: 'lava_bucket',
|
||||
redstone_wire: 'redstone',
|
||||
tripwire: 'tripwire_hook'
|
||||
}
|
||||
|
||||
export const getItemFromBlock = (block: import('prismarine-block').Block) => {
|
||||
const item = loadedData.blocks[blockToItemRemaps[block.name] ?? block.name]
|
||||
return item
|
||||
}
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ const commands: Array<{
|
|||
{
|
||||
command: ['/save'],
|
||||
async invoke () {
|
||||
await saveServer()
|
||||
await saveServer(false)
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import { chatInputValueGlobal } from './react/ChatContainer'
|
|||
import { fsState } from './loadSave'
|
||||
import { showOptionsModal } from './react/SelectOption'
|
||||
import widgets from './react/widgets'
|
||||
import { getItemFromBlock } from './botUtils'
|
||||
|
||||
// doesnt seem to work for now
|
||||
const customKeymaps = proxy(JSON.parse(localStorage.keymap || '{}'))
|
||||
|
|
@ -443,7 +444,7 @@ const toggleFly = (newState = !isFlying(), sendAbilities?: boolean) => {
|
|||
const selectItem = async () => {
|
||||
const block = bot.blockAtCursor(5)
|
||||
if (!block) return
|
||||
const itemId = loadedData.itemsByName[block.name]?.id
|
||||
const itemId = getItemFromBlock(block)?.id
|
||||
if (!itemId) return
|
||||
const Item = require('prismarine-item')(bot.version)
|
||||
const item = new Item(itemId, 1, 0)
|
||||
|
|
|
|||
|
|
@ -17,15 +17,16 @@ export function nameToMcOfflineUUID (name) {
|
|||
return (new UUID(javaUUID('OfflinePlayer:' + name))).toString()
|
||||
}
|
||||
|
||||
export async function savePlayers () {
|
||||
export async function savePlayers (autoSave: boolean) {
|
||||
if (autoSave && new URL(location.href).searchParams.get('noSave') === 'true') return
|
||||
//@ts-expect-error TODO
|
||||
await localServer!.savePlayersSingleplayer()
|
||||
}
|
||||
|
||||
// todo flying squid should expose save function instead
|
||||
export const saveServer = async () => {
|
||||
export const saveServer = async (autoSave = true) => {
|
||||
if (!localServer || fsState.isReadonly) return
|
||||
// todo
|
||||
const worlds = [(localServer as any).overworld] as Array<import('prismarine-world').world.World>
|
||||
await Promise.all([savePlayers(), ...worlds.map(async world => world.saveNow())])
|
||||
await Promise.all([savePlayers(autoSave), ...worlds.map(async world => world.saveNow())])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -141,7 +141,8 @@ export const miscUiState = proxy({
|
|||
loadedDataVersion: null as string | null,
|
||||
appLoaded: false,
|
||||
usingGamepadInput: false,
|
||||
appConfig: null as AppConfig | null
|
||||
appConfig: null as AppConfig | null,
|
||||
displaySearchInput: false,
|
||||
})
|
||||
|
||||
export const resetStateAfterDisconnect = () => {
|
||||
|
|
|
|||
1
src/globals.d.ts
vendored
1
src/globals.d.ts
vendored
|
|
@ -15,6 +15,7 @@ declare const customEvents: import('typed-emitter').default<{
|
|||
singleplayer (): void
|
||||
digStart ()
|
||||
gameLoaded (): void
|
||||
search (q: string): void
|
||||
}>
|
||||
declare const beforeRenderFrame: Array<() => void>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,2 +1,7 @@
|
|||
// workaround for mineflayer
|
||||
process.versions.node = '18.0.0'
|
||||
|
||||
if (!navigator.getGamepads) {
|
||||
console.warn('navigator.getGamepads is not available, adding a workaround')
|
||||
navigator.getGamepads ??= () => []
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ const commonCss = css`
|
|||
|
||||
/** @returns {boolean} */
|
||||
function isMobile () {
|
||||
return window.matchMedia('(pointer: coarse)').matches
|
||||
return window.matchMedia('(pointer: coarse)').matches || navigator.userAgent.includes('Mobile')
|
||||
}
|
||||
|
||||
// todo there are better workarounds and proper way to detect notch
|
||||
|
|
|
|||
|
|
@ -117,12 +117,8 @@ class Hud extends LitElement {
|
|||
this.isReady = true
|
||||
window.dispatchEvent(new CustomEvent('hud-ready', { detail: this }))
|
||||
|
||||
watchValue(options, (o) => {
|
||||
miscUiState.currentTouch = o.alwaysShowMobileControls || isMobile()
|
||||
this.showMobileControls(miscUiState.currentTouch)
|
||||
})
|
||||
|
||||
watchValue(miscUiState, o => {
|
||||
this.showMobileControls(o.currentTouch)
|
||||
//@ts-expect-error
|
||||
this.shadowRoot.host.style.display = o.gameLoaded ? 'block' : 'none'
|
||||
})
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import DispenserGui from 'minecraft-assets/minecraft-assets/data/1.17.1/gui/cont
|
|||
|
||||
import Dirt from 'minecraft-assets/minecraft-assets/data/1.17.1/blocks/dirt.png'
|
||||
import { subscribeKey } from 'valtio/utils'
|
||||
import MinecraftData from 'minecraft-data'
|
||||
import MinecraftData, { RecipeItem } from 'minecraft-data'
|
||||
import { getVersion } from 'prismarine-viewer/viewer/lib/version'
|
||||
import { versionToNumber } from 'prismarine-viewer/viewer/prepare/utils'
|
||||
import itemsPng from 'prismarine-viewer/public/textures/items.png'
|
||||
|
|
@ -20,6 +20,8 @@ import PrismarineBlockLoader from 'prismarine-block'
|
|||
import { flat } from '@xmcl/text-component'
|
||||
import mojangson from 'mojangson'
|
||||
import nbt from 'prismarine-nbt'
|
||||
import { splitEvery, equals } from 'rambda'
|
||||
import PItem, { Item } from 'prismarine-item'
|
||||
import { activeModalStack, hideCurrentModal, miscUiState, showModal } from './globalState'
|
||||
import invspriteJson from './invsprite.json'
|
||||
import { options } from './optionsStorage'
|
||||
|
|
@ -53,6 +55,7 @@ let lastWindow
|
|||
/** bot version */
|
||||
let version: string
|
||||
let PrismarineBlock: typeof PrismarineBlockLoader.Block
|
||||
let PrismarineItem: typeof Item
|
||||
|
||||
export const onGameLoad = (onLoad) => {
|
||||
let loaded = 0
|
||||
|
|
@ -65,6 +68,7 @@ export const onGameLoad = (onLoad) => {
|
|||
getImage({ path: 'items' }, onImageLoaded)
|
||||
getImage({ path: 'items-legacy' }, onImageLoaded)
|
||||
PrismarineBlock = PrismarineBlockLoader(version)
|
||||
PrismarineItem = PItem(version)
|
||||
|
||||
bot.on('windowOpen', (win) => {
|
||||
if (implementedContainersGuiMap[win.type]) {
|
||||
|
|
@ -76,12 +80,44 @@ export const onGameLoad = (onLoad) => {
|
|||
// todo format
|
||||
bot._client.emit('chat', {
|
||||
message: JSON.stringify({
|
||||
text: `[client error] cannot open unimplemented window ${win.id} (${win.type}). Items: ${win.slots.map(slot => slot?.name).join(', ')}`
|
||||
text: `[client error] cannot open unimplemented window ${win.id} (${win.type}). Slots: ${win.slots.map(item => getItemName(item) ?? '(empty)').join(', ')}`
|
||||
})
|
||||
})
|
||||
bot.currentWindow?.['close']()
|
||||
}
|
||||
})
|
||||
|
||||
bot.inventory.on('updateSlot', ((_oldSlot, oldItem, newItem) => {
|
||||
const oldSlot = _oldSlot as number
|
||||
if (!miscUiState.singleplayer) return
|
||||
const { craftingResultSlot } = bot.inventory
|
||||
if (oldSlot === craftingResultSlot && oldItem && !newItem) {
|
||||
for (let i = 1; i < 5; i++) {
|
||||
const count = bot.inventory.slots[i]?.count
|
||||
if (count && count > 1) {
|
||||
const slot = bot.inventory.slots[i]!
|
||||
slot.count--
|
||||
void bot.creative.setInventorySlot(i, slot)
|
||||
} else {
|
||||
void bot.creative.setInventorySlot(i, null)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
const craftingSlots = bot.inventory.slots.slice(1, 5)
|
||||
const resultingItem = getResultingRecipe(craftingSlots, 2)
|
||||
void bot.creative.setInventorySlot(craftingResultSlot, resultingItem ?? null)
|
||||
}) as any)
|
||||
|
||||
bot.on('windowClose', () => {
|
||||
// todo hide up to the window itself!
|
||||
hideCurrentModal()
|
||||
})
|
||||
|
||||
customEvents.on('search', (q) => {
|
||||
if (!lastWindow) return
|
||||
upJei(q)
|
||||
})
|
||||
}
|
||||
|
||||
const findTextureInBlockStates = (name) => {
|
||||
|
|
@ -192,7 +228,8 @@ const isFullBlock = (block: string) => {
|
|||
return shape[0] === 0 && shape[1] === 0 && shape[2] === 0 && shape[3] === 1 && shape[4] === 1 && shape[5] === 1
|
||||
}
|
||||
|
||||
const renderSlot = (slot: import('prismarine-item').Item, skipBlock = false): { texture: string, blockData?, scale?: number, slice?: number[] } | undefined => {
|
||||
type RenderSlot = Pick<import('prismarine-item').Item, 'name' | 'displayName'>
|
||||
const renderSlot = (slot: RenderSlot, skipBlock = false): { texture: string, blockData?, scale?: number, slice?: number[] } | undefined => {
|
||||
const itemName = slot.name
|
||||
const isItem = loadedData.itemsByName[itemName]
|
||||
const fullBlock = isFullBlock(itemName)
|
||||
|
|
@ -239,8 +276,8 @@ type PossibleItemProps = {
|
|||
Damage?: number
|
||||
display?: { Name?: JsonString } // {"text":"Knife","color":"white","italic":"true"}
|
||||
}
|
||||
export const getItemName = (item: import('prismarine-item').Item) => {
|
||||
if (!item.nbt) return
|
||||
export const getItemName = (item: import('prismarine-item').Item | null) => {
|
||||
if (!item?.nbt) return
|
||||
const itemNbt: PossibleItemProps = nbt.simplify(item.nbt)
|
||||
const customName = itemNbt.display?.Name
|
||||
if (!customName) return
|
||||
|
|
@ -260,22 +297,25 @@ export const renderSlotExternal = (slot) => {
|
|||
}
|
||||
}
|
||||
|
||||
const upInventory = (inventory: boolean) => {
|
||||
// inv.pwindow.inv.slots[2].displayName = 'test'
|
||||
// inv.pwindow.inv.slots[2].blockData = getBlockData('dirt')
|
||||
const updateSlots = (inventory ? bot.inventory : bot.currentWindow)!.slots.map(slot => {
|
||||
const mapSlots = (slots: Array<RenderSlot | Item | null>) => {
|
||||
return slots.map(slot => {
|
||||
// todo stateid
|
||||
if (!slot) return
|
||||
|
||||
try {
|
||||
const slotCustomProps = renderSlot(slot)
|
||||
Object.assign(slot, { ...slotCustomProps, displayName: getItemName(slot) ?? slot.displayName })
|
||||
Object.assign(slot, { ...slotCustomProps, displayName: ('nbt' in slot ? getItemName(slot) : undefined) ?? slot.displayName })
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
}
|
||||
return slot
|
||||
})
|
||||
const customSlots = updateSlots
|
||||
}
|
||||
|
||||
const upInventory = (isInventory: boolean) => {
|
||||
// inv.pwindow.inv.slots[2].displayName = 'test'
|
||||
// inv.pwindow.inv.slots[2].blockData = getBlockData('dirt')
|
||||
const customSlots = mapSlots((isInventory ? bot.inventory : bot.currentWindow)!.slots)
|
||||
lastWindow.pwindow.setSlots(customSlots)
|
||||
}
|
||||
|
||||
|
|
@ -299,6 +339,16 @@ const implementedContainersGuiMap = {
|
|||
'minecraft:crafting': 'CraftingWin'
|
||||
}
|
||||
|
||||
const upJei = (search: string) => {
|
||||
search = search.toLowerCase()
|
||||
// todo fix pre flat
|
||||
const matchedSlots = loadedData.itemsArray.map(x => {
|
||||
if (!x.displayName.toLowerCase().includes(search)) return null!
|
||||
return new PrismarineItem(x.id, 1)
|
||||
}).filter(Boolean)
|
||||
lastWindow.pwindow.win.jeiSlots = mapSlots(matchedSlots)
|
||||
}
|
||||
|
||||
const openWindow = (type: string | undefined) => {
|
||||
// if (activeModalStack.some(x => x.reactType?.includes?.('player_win:'))) {
|
||||
if (activeModalStack.length) { // game is not in foreground, don't close current modal
|
||||
|
|
@ -313,6 +363,7 @@ const openWindow = (type: string | undefined) => {
|
|||
if (type !== undefined && bot.currentWindow) bot.currentWindow['close']()
|
||||
lastWindow.destroy()
|
||||
lastWindow = null
|
||||
miscUiState.displaySearchInput = false
|
||||
destroyFn()
|
||||
})
|
||||
cleanLoadedImagesCache()
|
||||
|
|
@ -321,7 +372,7 @@ const openWindow = (type: string | undefined) => {
|
|||
inv.canvas.style.position = 'fixed'
|
||||
inv.canvas.style.inset = '0'
|
||||
// todo scaling
|
||||
inv.canvasManager.setScale(window.innerHeight < 480 ? 2 : window.innerHeight < 700 ? 3 : 4)
|
||||
inv.canvasManager.setScale(window.innerWidth < 470 ? 1.5 : window.innerHeight < 480 || window.innerWidth < 760 ? 2 : window.innerHeight < 700 ? 3 : 4)
|
||||
|
||||
inv.canvasManager.onClose = () => {
|
||||
hideCurrentModal()
|
||||
|
|
@ -330,10 +381,35 @@ const openWindow = (type: string | undefined) => {
|
|||
|
||||
lastWindow = inv
|
||||
const upWindowItems = () => {
|
||||
upInventory(type === undefined)
|
||||
void Promise.resolve().then(() => upInventory(type === undefined))
|
||||
}
|
||||
upWindowItems()
|
||||
|
||||
lastWindow.pwindow.touch = miscUiState.currentTouch
|
||||
lastWindow.pwindow.onJeiClick = (slotItem, _index, isRightclick) => {
|
||||
// slotItem is the slot from mapSlots
|
||||
const itemId = loadedData.itemsByName[slotItem.name]?.id
|
||||
if (!itemId) {
|
||||
console.error(`Item for block ${slotItem.name} not found`)
|
||||
return
|
||||
}
|
||||
const item = new PrismarineItem(itemId, isRightclick ? 64 : 1, slotItem.metadata)
|
||||
const freeSlot = bot.inventory.firstEmptyInventorySlot()
|
||||
if (freeSlot === null) return
|
||||
void bot.creative.setInventorySlot(freeSlot, item)
|
||||
}
|
||||
|
||||
if (bot.game.gameMode === 'creative') {
|
||||
lastWindow.pwindow.win.jeiSlotsPage = 0
|
||||
// todo workaround so inventory opens immediately (but still lags)
|
||||
setTimeout(() => {
|
||||
upJei('')
|
||||
})
|
||||
miscUiState.displaySearchInput = true
|
||||
} else {
|
||||
lastWindow.pwindow.win.jeiSlots = []
|
||||
}
|
||||
|
||||
if (type === undefined) {
|
||||
// player inventory
|
||||
bot.inventory.on('updateSlot', upWindowItems)
|
||||
|
|
@ -341,10 +417,6 @@ const openWindow = (type: string | undefined) => {
|
|||
bot.inventory.off('updateSlot', upWindowItems)
|
||||
}
|
||||
} else {
|
||||
bot.on('windowClose', () => {
|
||||
// todo hide up to the window itself!
|
||||
hideCurrentModal()
|
||||
})
|
||||
//@ts-expect-error
|
||||
bot.currentWindow.on('updateSlot', () => {
|
||||
upWindowItems()
|
||||
|
|
@ -357,3 +429,49 @@ let destroyFn = () => { }
|
|||
export const openPlayerInventory = () => {
|
||||
openWindow(undefined)
|
||||
}
|
||||
|
||||
const getResultingRecipe = (slots: Array<Item | null>, gridRows: number) => {
|
||||
const inputSlotsItems = slots.map(blockSlot => blockSlot?.type)
|
||||
let currentShape = splitEvery(gridRows, inputSlotsItems as Array<number | undefined | null>)
|
||||
// todo rewrite with candidates search
|
||||
if (currentShape.length > 1) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-for-in-array
|
||||
for (const slotX in currentShape[0]) {
|
||||
if (currentShape[0][slotX] !== undefined) {
|
||||
for (const [otherY] of Array.from({ length: gridRows }).entries()) {
|
||||
if (currentShape[otherY]?.[slotX] === undefined) {
|
||||
currentShape[otherY]![slotX] = null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
currentShape = currentShape.map(arr => arr.filter(x => x !== undefined)).filter(x => x.length !== 0)
|
||||
|
||||
// todo rewrite
|
||||
// eslint-disable-next-line @typescript-eslint/require-array-sort-compare
|
||||
const slotsIngredients = [...inputSlotsItems].sort().filter(item => item !== undefined)
|
||||
type Result = RecipeItem | undefined
|
||||
let shapelessResult: Result
|
||||
let shapeResult: Result
|
||||
outer: for (const [id, recipeVariants] of Object.entries(loadedData.recipes)) {
|
||||
for (const recipeVariant of recipeVariants) {
|
||||
if ('inShape' in recipeVariant && equals(currentShape, recipeVariant.inShape as number[][])) {
|
||||
shapeResult = recipeVariant.result!
|
||||
break outer
|
||||
}
|
||||
if ('ingredients' in recipeVariant && equals(slotsIngredients, recipeVariant.ingredients?.sort() as number[])) {
|
||||
shapelessResult = recipeVariant.result
|
||||
break outer
|
||||
}
|
||||
}
|
||||
}
|
||||
const result = shapeResult ?? shapelessResult
|
||||
if (!result) return
|
||||
const id = typeof result === 'number' ? result : Array.isArray(result) ? result[0] : result.id
|
||||
if (!id) return
|
||||
const count = (typeof result === 'number' ? undefined : Array.isArray(result) ? result[1] : result.count) ?? 1
|
||||
const metadata = typeof result === 'object' && !Array.isArray(result) ? result.metadata : undefined
|
||||
const item = new PrismarineItem(id, count, metadata)
|
||||
return item
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
import { useUsingTouch } from '@dimaka/interface'
|
||||
import { proxy, subscribe } from 'valtio'
|
||||
import { proxy, subscribe, useSnapshot } from 'valtio'
|
||||
import { useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { isCypress } from '../standaloneUtils'
|
||||
import { MessageFormatPart } from '../botUtils'
|
||||
import { miscUiState } from '../globalState'
|
||||
import { MessagePart } from './MessageFormatted'
|
||||
import './ChatContainer.css'
|
||||
import { isIos } from './utils'
|
||||
|
||||
export type Message = {
|
||||
parts: MessageFormatPart[],
|
||||
|
|
@ -13,7 +14,7 @@ export type Message = {
|
|||
faded?: boolean
|
||||
}
|
||||
|
||||
const MessageLine = ({ message }: {message: Message}) => {
|
||||
const MessageLine = ({ message }: { message: Message }) => {
|
||||
const classes = {
|
||||
'chat-message-fadeout': message.fading,
|
||||
'chat-message-fade': message.fading,
|
||||
|
|
@ -52,7 +53,7 @@ export const fadeMessage = (message: Message, initialTimeout: boolean, requestUp
|
|||
}
|
||||
|
||||
export default ({ messages, opacity = 1, fetchCompletionItems, opened, sendMessage, onClose }: Props) => {
|
||||
const usingTouch = useUsingTouch()
|
||||
const usingTouch = useSnapshot(miscUiState).currentTouch
|
||||
|
||||
const sendHistoryRef = useRef(JSON.parse(window.sessionStorage.chatHistory || '[]'))
|
||||
|
||||
|
|
@ -205,7 +206,7 @@ export default ({ messages, opacity = 1, fetchCompletionItems, opened, sendMessa
|
|||
{messages.map((m) => (
|
||||
<MessageLine key={m.id} message={m} />
|
||||
))}
|
||||
</div>}
|
||||
</div> || undefined}
|
||||
</div>
|
||||
|
||||
<div className={`chat-wrapper chat-input-wrapper ${usingTouch ? 'input-mobile' : ''}`} hidden={!opened}>
|
||||
|
|
@ -220,78 +221,81 @@ export default ({ messages, opacity = 1, fetchCompletionItems, opened, sendMessa
|
|||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
<input
|
||||
value=''
|
||||
type="text"
|
||||
className="chat-mobile-hidden"
|
||||
id="chatinput-next-command"
|
||||
spellCheck={false}
|
||||
autoComplete="off"
|
||||
onFocus={() => auxInputFocus('ArrowUp')}
|
||||
onChange={() => { }}
|
||||
/>
|
||||
<input
|
||||
defaultValue=''
|
||||
ref={chatInput}
|
||||
type="text"
|
||||
className="chat-input"
|
||||
id="chatinput"
|
||||
spellCheck={false}
|
||||
autoComplete="off"
|
||||
aria-autocomplete="both"
|
||||
onChange={onMainInputChange}
|
||||
onKeyDown={(e) => {
|
||||
if (e.code === 'ArrowUp') {
|
||||
if (chatHistoryPos.current === 0) return
|
||||
if (chatHistoryPos.current === sendHistoryRef.current.length) { // started navigating history
|
||||
inputCurrentlyEnteredValue.current = e.currentTarget.value
|
||||
}
|
||||
chatHistoryPos.current--
|
||||
updateInputValue(sendHistoryRef.current[chatHistoryPos.current] || '')
|
||||
} else if (e.code === 'ArrowDown') {
|
||||
if (chatHistoryPos.current === sendHistoryRef.current.length) return
|
||||
chatHistoryPos.current++
|
||||
updateInputValue(sendHistoryRef.current[chatHistoryPos.current] || inputCurrentlyEnteredValue.current || '')
|
||||
<form onSubmit={(e) => {
|
||||
e.preventDefault()
|
||||
const message = chatInput.current.value
|
||||
if (message) {
|
||||
setSendHistory([...sendHistoryRef.current, message])
|
||||
const result = sendMessage?.(message)
|
||||
if (result !== false) {
|
||||
onClose?.()
|
||||
}
|
||||
if (e.code === 'Tab') {
|
||||
if (completionItemsSource.length) {
|
||||
if (completionItems.length) {
|
||||
acceptComplete(completionItems[0])
|
||||
}
|
||||
}}>
|
||||
{isIos && <input
|
||||
value=''
|
||||
type="text"
|
||||
className="chat-mobile-hidden"
|
||||
id="chatinput-next-command"
|
||||
spellCheck={false}
|
||||
autoComplete="off"
|
||||
onFocus={() => auxInputFocus('ArrowUp')}
|
||||
onChange={() => { }}
|
||||
/>}
|
||||
<input
|
||||
defaultValue=''
|
||||
ref={chatInput}
|
||||
type="text"
|
||||
className="chat-input"
|
||||
id="chatinput"
|
||||
spellCheck={false}
|
||||
autoComplete="off"
|
||||
aria-autocomplete="both"
|
||||
onChange={onMainInputChange}
|
||||
onKeyDown={(e) => {
|
||||
if (e.code === 'ArrowUp') {
|
||||
if (chatHistoryPos.current === 0) return
|
||||
if (chatHistoryPos.current === sendHistoryRef.current.length) { // started navigating history
|
||||
inputCurrentlyEnteredValue.current = e.currentTarget.value
|
||||
}
|
||||
} else {
|
||||
void fetchCompletions(false)
|
||||
chatHistoryPos.current--
|
||||
updateInputValue(sendHistoryRef.current[chatHistoryPos.current] || '')
|
||||
} else if (e.code === 'ArrowDown') {
|
||||
if (chatHistoryPos.current === sendHistoryRef.current.length) return
|
||||
chatHistoryPos.current++
|
||||
updateInputValue(sendHistoryRef.current[chatHistoryPos.current] || inputCurrentlyEnteredValue.current || '')
|
||||
}
|
||||
e.preventDefault()
|
||||
}
|
||||
if (e.code === 'Space') {
|
||||
resetCompletionItems()
|
||||
if (chatInput.current.value.startsWith('/')) {
|
||||
// alternative we could just simply use keyup, but only with keydown we can display suggestions popup as soon as possible
|
||||
void fetchCompletions(true, getCompleteValue(getDefaultCompleteValue() + ' '))
|
||||
if (e.code === 'Tab') {
|
||||
if (completionItemsSource.length) {
|
||||
if (completionItems.length) {
|
||||
acceptComplete(completionItems[0])
|
||||
}
|
||||
} else {
|
||||
void fetchCompletions(false)
|
||||
}
|
||||
e.preventDefault()
|
||||
}
|
||||
}
|
||||
if (e.code === 'Enter') {
|
||||
const message = chatInput.current.value
|
||||
if (message) {
|
||||
setSendHistory([...sendHistoryRef.current, message])
|
||||
const result = sendMessage?.(message)
|
||||
if (result !== false) {
|
||||
onClose?.()
|
||||
if (e.code === 'Space') {
|
||||
resetCompletionItems()
|
||||
if (chatInput.current.value.startsWith('/')) {
|
||||
// alternative we could just simply use keyup, but only with keydown we can display suggestions popup as soon as possible
|
||||
void fetchCompletions(true, getCompleteValue(getDefaultCompleteValue() + ' '))
|
||||
}
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<input
|
||||
value=''
|
||||
type="text"
|
||||
className="chat-mobile-hidden"
|
||||
id="chatinput-prev-command"
|
||||
spellCheck={false}
|
||||
autoComplete="off"
|
||||
onFocus={() => auxInputFocus('ArrowDown')}
|
||||
onChange={() => { }}
|
||||
/>
|
||||
}}
|
||||
/>
|
||||
{isIos && <input
|
||||
value=''
|
||||
type="text"
|
||||
className="chat-mobile-hidden"
|
||||
id="chatinput-prev-command"
|
||||
spellCheck={false}
|
||||
autoComplete="off"
|
||||
onFocus={() => auxInputFocus('ArrowDown')}
|
||||
onChange={() => { }}
|
||||
/>}
|
||||
<button type='submit' style={{ visibility: 'hidden' }} />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -27,26 +27,29 @@ export default ({ cancelClick, createClick, customizeClick, versions, defaultVer
|
|||
}, [])
|
||||
|
||||
return <Screen title="Create world" backdrop="dirt">
|
||||
<div style={{ display: 'flex' }}>
|
||||
<form style={{ display: 'flex' }} onSubmit={(e) => {
|
||||
e.preventDefault()
|
||||
createClick()
|
||||
}}>
|
||||
<Input
|
||||
autoFocus
|
||||
value={title}
|
||||
onChange={({ target: { value } }) => {
|
||||
creatingWorldState.title = value
|
||||
}}
|
||||
onEnterPress={() => {
|
||||
createClick()
|
||||
}}
|
||||
placeholder='World name'
|
||||
/>
|
||||
<select value={version} onChange={({ target: { value } }) => {
|
||||
<select value={version} style={{
|
||||
background: 'gray',
|
||||
color: 'white'
|
||||
}} onChange={({ target: { value } }) => {
|
||||
creatingWorldState.version = value
|
||||
}}>
|
||||
{versions.map(({ version, label }) => {
|
||||
return <option key={version} value={version}>{label}</option>
|
||||
})}
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
<div style={{ display: 'flex' }}>
|
||||
<Button onClick={() => {
|
||||
const index = worldTypes.indexOf(type)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { useUsingTouch } from '@dimaka/interface'
|
||||
import { useEffect, useState } from 'react'
|
||||
import Button from './Button'
|
||||
import { useUsingTouch } from './utils'
|
||||
|
||||
export default () => {
|
||||
const [fullScreen, setFullScreen] = useState(false)
|
||||
|
|
|
|||
|
|
@ -1,21 +1,17 @@
|
|||
import React, { useEffect, useRef } from 'react'
|
||||
import styles from './input.module.css'
|
||||
import { useUsingTouch } from './utils'
|
||||
|
||||
interface Props extends React.ComponentProps<'input'> {
|
||||
autoFocus?: boolean
|
||||
onEnterPress?: (e) => void
|
||||
}
|
||||
|
||||
export default ({ autoFocus, onEnterPress, ...inputProps }: Props) => {
|
||||
export default ({ autoFocus, ...inputProps }: Props) => {
|
||||
const ref = useRef<HTMLInputElement>(null!)
|
||||
const isTouch = useUsingTouch()
|
||||
|
||||
useEffect(() => {
|
||||
if (onEnterPress) {
|
||||
ref.current.addEventListener('keydown', (e) => {
|
||||
if (e.code === 'Enter') onEnterPress(e)
|
||||
})
|
||||
}
|
||||
if (!autoFocus || matchMedia('(pointer: coarse)').matches) return // Don't make screen keyboard popup on mobile
|
||||
if (!autoFocus || isTouch) return // Don't make screen keyboard popup on mobile
|
||||
ref.current.focus()
|
||||
}, [])
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import { LeftTouchArea, RightTouchArea, useInterfaceState, useUsingTouch } from '@dimaka/interface'
|
||||
import { LeftTouchArea, RightTouchArea, useInterfaceState } from '@dimaka/interface'
|
||||
import { css } from '@emotion/css'
|
||||
import { useSnapshot } from 'valtio'
|
||||
import { contro } from '../controls'
|
||||
import { miscUiState, activeModalStack } from '../globalState'
|
||||
import { watchValue, options } from '../optionsStorage'
|
||||
import { useUsingTouch } from './utils'
|
||||
|
||||
// todo
|
||||
useInterfaceState.setState({
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { useSnapshot } from 'valtio'
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { activeModalStack } from '../globalState'
|
||||
import { UAParser } from 'ua-parser-js'
|
||||
import { activeModalStack, miscUiState } from '../globalState'
|
||||
|
||||
export const useIsModalActive = (modal: string) => {
|
||||
return useSnapshot(activeModalStack).at(-1)?.reactType === modal
|
||||
|
|
@ -25,3 +26,11 @@ export function useDidUpdateEffect (fn, inputs) {
|
|||
}
|
||||
}, inputs)
|
||||
}
|
||||
|
||||
export const useUsingTouch = () => {
|
||||
return useSnapshot(miscUiState).currentTouch
|
||||
}
|
||||
|
||||
export const ua = new UAParser(navigator.userAgent)
|
||||
|
||||
export const isIos = ua.getOS().name === 'iOS'
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import SoundMuffler from './react/SoundMuffler'
|
|||
import TouchControls from './react/TouchControls'
|
||||
import widgets from './react/widgets'
|
||||
import { useIsWidgetActive } from './react/utils'
|
||||
import GlobalSearchInput from './GlobalSearchInput'
|
||||
|
||||
const Portal = ({ children, to }) => {
|
||||
return createPortal(children, to)
|
||||
|
|
@ -63,6 +64,7 @@ const InGameUi = () => {
|
|||
<Portal to={document.body}>
|
||||
{/* becaues of z-index */}
|
||||
<TouchControls />
|
||||
<GlobalSearchInput />
|
||||
</Portal>
|
||||
</>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
.backdrop {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
height: 100dvh;
|
||||
background: rgba(0, 0, 0, 0.75);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ body {
|
|||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
font-family: minecraft, mojangles, monospace;
|
||||
z-index: -5;
|
||||
}
|
||||
|
||||
#react-root {
|
||||
|
|
@ -148,6 +149,11 @@ body {
|
|||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
.full-svg svg {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.muted {
|
||||
color: #999;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
import { subscribeKey } from 'valtio/utils'
|
||||
import { options, watchValue } from './optionsStorage'
|
||||
import { reloadChunks } from './utils'
|
||||
import { miscUiState } from './globalState'
|
||||
import { isMobile } from './menus/components/common'
|
||||
|
||||
subscribeKey(options, 'renderDistance', reloadChunks)
|
||||
subscribeKey(options, 'multiplayerRenderDistance', reloadChunks)
|
||||
|
|
@ -14,7 +16,17 @@ watchValue(options, o => {
|
|||
document.documentElement.style.setProperty('--guiScale', `${o.guiScale}`)
|
||||
})
|
||||
|
||||
/** happens once */
|
||||
export const watchOptionsAfterViewerInit = () => {
|
||||
const updateTouch = (o) => {
|
||||
miscUiState.currentTouch = o.alwaysShowMobileControls || isMobile()
|
||||
}
|
||||
|
||||
watchValue(options, updateTouch)
|
||||
window.matchMedia('(pointer: coarse)').addEventListener('change', (e) => {
|
||||
updateTouch(options)
|
||||
})
|
||||
|
||||
watchValue(options, o => {
|
||||
if (!viewer) return
|
||||
viewer.world.showChunkBorders = o.showChunkBorders
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue