diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..f68b708
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
+target/
+Cargo.lock
+
+/nap_proto/nap.proto
+/nap_proto/bin.server.proto
+
+/nap_sdk.toml
+/nap_gameserver.toml
diff --git a/Cargo.toml b/Cargo.toml
new file mode 100644
index 0000000..c6cf57e
--- /dev/null
+++ b/Cargo.toml
@@ -0,0 +1,76 @@
+[workspace]
+members = ["nap_common", "nap_sdk", "nap_proto", "nap_gameserver", "nap_data"]
+resolver = "2"
+
+[workspace.package]
+version = "0.1.0"
+
+[workspace.dependencies]
+# Runtime
+tokio = { version = "1.36.0", features = ["full"] }
+tokio-util = { version = "0.7.10", features = ["io"] }
+
+# Serialization
+serde = { version = "1.0.197", features = ["derive"] }
+serde_json = "1.0.114"
+toml = "0.8.4"
+rbase64 = "2.0.3"
+prost = "0.12.3"
+prost-types = "0.12.3"
+prost-build = "0.12.3"
+
+# Cryptography
+password-hash = { version = "0.5.0", features = ["alloc", "rand_core"] }
+pbkdf2 = { version = "0.12.2", features = ["simple"] }
+rand_mt = "4.2.2"
+rsa = { version = "0.9.6", features = [
+ "sha1",
+ "nightly",
+ "pkcs5",
+ "serde",
+ "sha2",
+] }
+
+# Http
+axum = "0.7.5"
+
+# Database
+sqlx = { version = "0.7.4", features = ["postgres", "runtime-tokio-rustls"] }
+
+# Logging
+env_logger = "0.11.3"
+tracing = "0.1.40"
+tracing-futures = "0.2.5"
+tracing-log = { version = "0.2.0", features = ["std", "log-tracer"] }
+tracing-subscriber = { version = "0.3.18", features = [
+ "env-filter",
+ "registry",
+ "std",
+ "tracing",
+ "tracing-log",
+] }
+tracing-bunyan-formatter = "0.3.9"
+
+# Util
+thiserror = "1.0.61"
+paste = "1.0.15"
+hex = "0.4.3"
+rand = "0.8.5"
+byteorder = "1.5.0"
+atomic_enum = "0.3.0"
+num_enum = "0.7.2"
+dashmap = "6.0.1"
+regex = "1.10.5"
+ansi_term = "0.12.1"
+
+# Internal
+common = { path = "nap_common" }
+data = { path = "nap_data" }
+proto = { path = "nap_proto" }
+proto_gen = { path = "nap_proto/proto_gen" }
+
+[profile.release]
+strip = true # Automatically strip symbols from the binary.
+lto = true # Link-time optimization.
+opt-level = 3 # Optimize for speed.
+codegen-units = 1 # Maximum size reduction optimizations.
diff --git a/README.md b/README.md
index e19e1c9..85b6413 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,59 @@
# JaneDoe-ZS
-Server emulator for Zenless Zone Zero 1.1.1
\ No newline at end of file
+#### Zenless Zone Zero 1.1.1 server emulator written in Rust.
+![screenshot](https://git.xeondev.com/NewEriduPubSec/JaneDoe-ZS/raw/branch/master/screenshot.png)
+
+### Current features
+- Logging in
+- Fully playable prologue
+- Player progress saving with PostgreSQL
+- Unlock all characters
+- Training battle
+
+### Requirements
+- [Rust](https://www.rust-lang.org/tools/install)
+- [PostgreSQL](https://www.postgresql.org/download/)
+
+**NOTE**: Nightly Rust is required to build the project. To install it, first install
+Rust itself, then run the following command:
+
+```sh
+rustup toolchain install nightly
+rustup default nightly
+```
+
+### Setup
+#### Server
+##### a) building from sources
+```
+git clone https://git.xeondev.com/NewEriduPubSec/JaneDoe-ZS.git
+cd JaneDoe-ZS
+cargo run --bin nap-sdk
+cargo run --bin nap-gameserver
+```
+
+##### b) using pre-built binaries
+Navigate to the [Releases](https://git.xeondev.com/NewEriduPubSec/JaneDoe-ZS/releases)
+page and download the latest release for your platform.
+Launch `nap-sdk` and `nap-gameserver`
+
+#### Database
+You have to put your PostgreSQL database credentials in both `nap_sdk.toml` and `nap_gameserver.toml` configuration files.
+```
+[database]
+username = "root"
+password = "root"
+host = "localhost:5432"
+name = "nap"
+```
+
+### Connecting
+[Get ZZZ 1.1.1 beta client](https://nogatekeep.ing/assets/nap/pc/napcnbeta_1.1.1.7z),
+apply [encryption patch](https://git.xeondev.com/NewEriduPubSec/JaneDoe-Patch) and follow its instructions.
+**NOTE**: You should create a game account. By default, you can do so at http://127.0.0.1:21000/account/register
+
+### Troubleshooting
+[Visit our discord](https://discord.xeondev.com/) if you have any questions/issues
+
+### Support
+If you want to support this project, feel free to [send a tip via boosty](https://boosty.to/xeondev/donate)
diff --git a/assets/FileCfg/AvatarBaseTemplateTb.json b/assets/FileCfg/AvatarBaseTemplateTb.json
new file mode 100644
index 0000000..bda50b6
--- /dev/null
+++ b/assets/FileCfg/AvatarBaseTemplateTb.json
@@ -0,0 +1,394 @@
+[
+ {
+ "ID": 1011,
+ "CodeName": "Avatar_Female_Size02_Anbi_En",
+ "Name": "Avatar_Female_Size02_Anbi",
+ "FullName": "Avatar_Female_Size02_Anbi_FullName",
+ "AudioEventReplaceParam": "anbi",
+ "AudioBank": "BK_Anbi|BK_CHR_Common|BK_Anbi_VO",
+ "HitTypes": [101],
+ "ElementTypes": [203],
+ "Unk1": 2,
+ "Gender": 2,
+ "Camp": 1,
+ "Unk2": ["1:1:2", "2:203:2"]
+ },
+ {
+ "ID": 1021,
+ "CodeName": "Avatar_Female_Size01_Tsubaki_En",
+ "Name": "Avatar_Female_Size01_Tsubaki",
+ "FullName": "Avatar_Female_Size01_Tsubaki_FullName",
+ "AudioEventReplaceParam": "tsubaki",
+ "AudioBank": "BK_Tsubaki|BK_CHR_Common|BK_Tsubaki_VO",
+ "HitTypes": [101],
+ "ElementTypes": [200],
+ "Unk1": 1,
+ "Gender": 2,
+ "Camp": 1,
+ "Unk2": ["1:1:2", "2:200:2"]
+ },
+ {
+ "ID": 1031,
+ "CodeName": "Avatar_Female_Size02_Nostradamus_En",
+ "Name": "Avatar_Female_Size02_Nostradamus",
+ "FullName": "Avatar_Female_Size02_Nostradamus_FullName",
+ "AudioEventReplaceParam": "nicole",
+ "AudioBank": "BK_Nicole|BK_CHR_Common|BK_Nicole_VO",
+ "HitTypes": [102],
+ "ElementTypes": [205],
+ "Unk1": 4,
+ "Gender": 2,
+ "Camp": 1,
+ "Unk2": ["1:1:2", "2:205:2"]
+ },
+ {
+ "ID": 1041,
+ "CodeName": "Avatar_Female_Size02_Longinus_En",
+ "Name": "Avatar_Female_Size02_Longinus",
+ "FullName": "Avatar_Female_Size02_Longinus_FullName",
+ "AudioEventReplaceParam": "longinus",
+ "AudioBank": "BK_Longinus|BK_CHR_Common|BK_Longinus_VO",
+ "HitTypes": [101],
+ "ElementTypes": [201],
+ "Unk1": 1,
+ "Gender": 2,
+ "Camp": 5,
+ "Unk2": ["1:5:2", "2:201:2"]
+ },
+ {
+ "ID": 1061,
+ "CodeName": "Avatar_Female_Size01_Corin_En",
+ "Name": "Avatar_Female_Size01_Corin",
+ "FullName": "Avatar_Female_Size01_Corin_FullName",
+ "AudioEventReplaceParam": "corin",
+ "AudioBank": "BK_Corin|BK_CHR_Common|BK_Corin_VO",
+ "HitTypes": [101],
+ "ElementTypes": [200],
+ "Unk1": 1,
+ "Gender": 2,
+ "Camp": 2,
+ "Unk2": ["1:2:2", "2:200:2"]
+ },
+ {
+ "ID": 1071,
+ "CodeName": "Avatar_Female_Size03_Caesar_En",
+ "Name": "Avatar_Female_Size03_Caesar",
+ "FullName": "Avatar_Female_Size03_Caesar_FullName",
+ "AudioEventReplaceParam": "caesar",
+ "AudioBank": "BK_Caesar|BK_CHR_Common|BK_Caesar_VO",
+ "HitTypes": [101, 102],
+ "ElementTypes": [200],
+ "Unk1": 5,
+ "Gender": 2,
+ "Camp": 4,
+ "Unk2": ["1:4:2", "2:200:2"]
+ },
+ {
+ "ID": 1081,
+ "CodeName": "Avatar_Male_Size03_Billy_En",
+ "Name": "Avatar_Male_Size03_Billy",
+ "FullName": "Avatar_Male_Size03_Billy_FullName",
+ "AudioEventReplaceParam": "billy",
+ "AudioBank": "BK_Billy|BK_CHR_Common|BK_Billy_VO",
+ "HitTypes": [103],
+ "ElementTypes": [200],
+ "Unk1": 1,
+ "Gender": 1,
+ "Camp": 1,
+ "Unk2": ["1:1:2", "2:200:2"]
+ },
+ {
+ "ID": 1091,
+ "CodeName": "Avatar_Female_Size02_Unagi_En",
+ "Name": "Avatar_Female_Size02_Unagi",
+ "FullName": "Avatar_Female_Size02_Unagi_FullName",
+ "AudioEventReplaceParam": "unagi",
+ "AudioBank": "BK_Unagi|BK_CHR_Common|BK_Unagi_VO",
+ "HitTypes": [101],
+ "ElementTypes": [202],
+ "Unk1": 1,
+ "Gender": 2,
+ "Camp": 6,
+ "Unk2": ["1:6:2", "2:202:2"]
+ },
+ {
+ "ID": 1101,
+ "CodeName": "Avatar_Female_Size01_OokumaMari_En",
+ "Name": "Avatar_Female_Size01_OokumaMari",
+ "FullName": "Avatar_Female_Size01_OokumaMari_FullName",
+ "AudioEventReplaceParam": "koleda",
+ "AudioBank": "BK_Koleda|BK_CHR_Common|BK_Koleda_VO",
+ "HitTypes": [102],
+ "ElementTypes": [201],
+ "Unk1": 2,
+ "Gender": 2,
+ "Camp": 3,
+ "Unk2": ["1:3:2", "2:201:2"]
+ },
+ {
+ "ID": 1111,
+ "CodeName": "Avatar_Male_Size03_Anton_En",
+ "Name": "Avatar_Male_Size03_Anton",
+ "FullName": "Avatar_Male_Size03_Anton_FullName",
+ "AudioEventReplaceParam": "anton",
+ "AudioBank": "BK_Anton|BK_CHR_Common|BK_Anton_VO",
+ "HitTypes": [103],
+ "ElementTypes": [203],
+ "Unk1": 1,
+ "Gender": 1,
+ "Camp": 3,
+ "Unk2": ["1:3:2", "2:203:2"]
+ },
+ {
+ "ID": 1121,
+ "CodeName": "Avatar_Male_Size03_Ben_En",
+ "Name": "Avatar_Male_Size03_Ben",
+ "FullName": "Avatar_Male_Size03_Ben_FullName",
+ "AudioEventReplaceParam": "ben",
+ "AudioBank": "BK_Ben|BK_CHR_Common|BK_Ben_VO",
+ "HitTypes": [102],
+ "ElementTypes": [201],
+ "Unk1": 5,
+ "Gender": 1,
+ "Camp": 3,
+ "Unk2": ["1:3:2", "2:201:2"]
+ },
+ {
+ "ID": 1131,
+ "CodeName": "Avatar_Female_Size01_Aokaku_En",
+ "Name": "Avatar_Female_Size01_Aokaku",
+ "FullName": "Avatar_Female_Size01_Aokaku_FullName",
+ "AudioEventReplaceParam": "aokaku",
+ "AudioBank": "BK_Aokaku|BK_CHR_Common|BK_Aokaku_VO",
+ "HitTypes": [101],
+ "ElementTypes": [202],
+ "Unk1": 4,
+ "Gender": 2,
+ "Camp": 6,
+ "Unk2": ["1:6:2", "2:202:2"]
+ },
+ {
+ "ID": 1141,
+ "CodeName": "Avatar_Male_Size03_Lycaon_En",
+ "Name": "Avatar_Male_Size03_Lycaon",
+ "FullName": "Avatar_Male_Size03_Lycaon_FullName",
+ "AudioEventReplaceParam": "lycaon",
+ "AudioBank": "BK_Lycaon|BK_CHR_Common|BK_Lycaon_VO",
+ "HitTypes": [102],
+ "ElementTypes": [202],
+ "Unk1": 2,
+ "Gender": 1,
+ "Camp": 2,
+ "Unk2": ["1:2:2", "2:202:2"]
+ },
+ {
+ "ID": 1151,
+ "CodeName": "Avatar_Female_Size01_Lucy_En",
+ "Name": "Avatar_Female_Size01_Lucy",
+ "FullName": "Avatar_Female_Size01_Lucy_FullName",
+ "AudioEventReplaceParam": "lucy",
+ "AudioBank": "BK_Lucy|BK_CHR_Common|BK_Lucy_VO",
+ "HitTypes": [102],
+ "ElementTypes": [201],
+ "Unk1": 4,
+ "Gender": 2,
+ "Camp": 4,
+ "Unk2": ["1:4:2", "2:201:2"]
+ },
+ {
+ "ID": 1161,
+ "CodeName": "Avatar_Male_Size02_Lighter_En",
+ "Name": "Avatar_Male_Size02_Lighter",
+ "FullName": "Avatar_Male_Size02_Lighter_FullName",
+ "AudioEventReplaceParam": "lighter",
+ "AudioBank": "BK_Lighter|BK_CHR_Common|BK_Lighter_VO",
+ "HitTypes": [102],
+ "ElementTypes": [201],
+ "Unk1": 1,
+ "Gender": 1,
+ "Camp": 4,
+ "Unk2": ["1:4:2", "2:201:2"]
+ },
+ {
+ "ID": 1171,
+ "CodeName": "Avatar_Female_Size02_Burnice_En",
+ "Name": "Avatar_Female_Size02_Burnice",
+ "FullName": "Avatar_Female_Size02_Burnice_FullName",
+ "AudioEventReplaceParam": "burnice",
+ "AudioBank": "BK_Burnice|BK_CHR_Common|BK_Burnice_VO",
+ "HitTypes": [103],
+ "ElementTypes": [201],
+ "Unk1": 3,
+ "Gender": 2,
+ "Camp": 4,
+ "Unk2": ["1:4:2", "2:201:2"]
+ },
+ {
+ "ID": 1181,
+ "CodeName": "Avatar_Female_Size03_Lisa_En",
+ "Name": "Avatar_Female_Size03_Lisa",
+ "FullName": "Avatar_Female_Size03_Lisa_FullName",
+ "AudioEventReplaceParam": "lisa",
+ "AudioBank": "BK_Lisa|BK_CHR_Common|BK_Lisa_VO",
+ "HitTypes": [103],
+ "ElementTypes": [203],
+ "Unk1": 3,
+ "Gender": 2,
+ "Camp": 3,
+ "Unk2": ["1:3:2", "2:203:2"]
+ },
+ {
+ "ID": 1191,
+ "CodeName": "Avatar_Female_Size02_Ellen_En",
+ "Name": "Avatar_Female_Size02_Ellen",
+ "FullName": "Avatar_Female_Size02_Ellen_FullName",
+ "AudioEventReplaceParam": "ellen",
+ "AudioBank": "BK_Ellen|BK_CHR_Common|BK_Ellen_VO",
+ "HitTypes": [101],
+ "ElementTypes": [202],
+ "Unk1": 1,
+ "Gender": 2,
+ "Camp": 2,
+ "Unk2": ["1:2:2", "2:202:2"]
+ },
+ {
+ "ID": 1201,
+ "CodeName": "Avatar_Male_Size01_Harumasa_En",
+ "Name": "Avatar_Male_Size01_Harumasa",
+ "FullName": "Avatar_Male_Size01_Harumasa_FullName",
+ "AudioEventReplaceParam": "harumasa",
+ "AudioBank": "BK_Harumasa|BK_CHR_Common|BK_Harumasa_VO",
+ "HitTypes": [103],
+ "ElementTypes": [203],
+ "Unk1": 1,
+ "Gender": 1,
+ "Camp": 6,
+ "Unk2": ["1:6:2", "2:200:2"]
+ },
+ {
+ "ID": 1211,
+ "CodeName": "Avatar_Female_Size03_Rina_En",
+ "Name": "Avatar_Female_Size03_Rina",
+ "FullName": "Avatar_Female_Size03_Rina_FullName",
+ "AudioEventReplaceParam": "rina",
+ "AudioBank": "BK_Rina|BK_CHR_Common|BK_Rina_VO",
+ "HitTypes": [102],
+ "ElementTypes": [203],
+ "Unk1": 4,
+ "Gender": 2,
+ "Camp": 2,
+ "Unk2": ["1:2:2", "2:203:2"]
+ },
+ {
+ "ID": 1221,
+ "CodeName": "Avatar_Female_Size03_Yanagi_En",
+ "Name": "Avatar_Female_Size03_Yanagi",
+ "FullName": "Avatar_Female_Size03_Yanagi_FullName",
+ "AudioEventReplaceParam": "yanagi",
+ "AudioBank": "BK_Yanagi|BK_CHR_Common|BK_Yanagi_VO",
+ "HitTypes": [101],
+ "ElementTypes": [203],
+ "Unk1": 3,
+ "Gender": 2,
+ "Camp": 6,
+ "Unk2": ["1:6:2", "2:203:2"]
+ },
+ {
+ "ID": 1241,
+ "CodeName": "Avatar_Female_Size03_ZhuYuan_En",
+ "Name": "Avatar_Female_Size03_ZhuYuan",
+ "FullName": "Avatar_Female_Size03_ZhuYuan_FullName",
+ "AudioEventReplaceParam": "ZhuYuan",
+ "AudioBank": "BK_ZhuYuan|BK_CHR_Common|BK_ZhuYuan_VO",
+ "HitTypes": [103],
+ "ElementTypes": [205],
+ "Unk1": 1,
+ "Gender": 2,
+ "Camp": 7,
+ "Unk2": ["1:7:2", "3:4:1"]
+ },
+ {
+ "ID": 1251,
+ "CodeName": "Avatar_Female_Size01_QingYi_En",
+ "Name": "Avatar_Female_Size01_QingYi",
+ "FullName": "Avatar_Female_Size01_QingYi_FullName",
+ "AudioEventReplaceParam": "qingyi",
+ "AudioBank": "BK_QingYi|BK_CHR_Common|BK_QingYi_VO",
+ "HitTypes": [102],
+ "ElementTypes": [203],
+ "Unk1": 2,
+ "Gender": 2,
+ "Camp": 7,
+ "Unk2": ["1:7:2", "3:1:1"]
+ },
+ {
+ "ID": 1261,
+ "CodeName": "Avatar_Female_Size03_JaneDoe_En",
+ "Name": "Avatar_Female_Size03_JaneDoe",
+ "FullName": "Avatar_Female_Size03_JaneDoe_FullName",
+ "AudioEventReplaceParam": "janedoe",
+ "AudioBank": "BK_JaneDoe|BK_CHR_Common|BK_JaneDoe_VO",
+ "HitTypes": [101],
+ "ElementTypes": [200],
+ "Unk1": 3,
+ "Gender": 2,
+ "Camp": 7,
+ "Unk2": ["1:7:2", "3:3:2"]
+ },
+ {
+ "ID": 1271,
+ "CodeName": "Avatar_Male_Size01_Seth_En",
+ "Name": "Avatar_Male_Size01_Seth",
+ "FullName": "Avatar_Male_Size01_Seth_FullName",
+ "AudioEventReplaceParam": "seth",
+ "AudioBank": "BK_Seth|BK_CHR_Common|BK_Seth_VO",
+ "HitTypes": [101],
+ "ElementTypes": [203],
+ "Unk1": 5,
+ "Gender": 1,
+ "Camp": 7,
+ "Unk2": ["1:7:2", "2:203:2"]
+ },
+ {
+ "ID": 1281,
+ "CodeName": "Avatar_Female_Size01_Clara_En",
+ "Name": "Avatar_Female_Size01_Clara",
+ "FullName": "Avatar_Female_Size01_Clara_FullName",
+ "AudioEventReplaceParam": "clara",
+ "AudioBank": "BK_Clara|BK_CHR_Common|BK_Clara_VO",
+ "HitTypes": [101],
+ "ElementTypes": [200],
+ "Unk1": 3,
+ "Gender": 2,
+ "Camp": 4,
+ "Unk2": ["1:4:2", "2:200:2"]
+ },
+ {
+ "ID": 2011,
+ "CodeName": "Avatar_Male_Size01_Wise_En",
+ "Name": "Avatar_Male_Size01_Wise",
+ "FullName": "Avatar_Male_Size01_Wise_FullName",
+ "AudioEventReplaceParam": "wise",
+ "AudioBank": "BK_Wise",
+ "HitTypes": [0],
+ "ElementTypes": [1],
+ "Unk1": 1,
+ "Gender": 1,
+ "Camp": 0,
+ "Unk2": ["1:0:2", "2:1:2"]
+ },
+ {
+ "ID": 2021,
+ "CodeName": "Avatar_Female_Size02_Belle_En",
+ "Name": "Avatar_Female_Size02_Belle",
+ "FullName": "Avatar_Female_Size02_Belle_FullName",
+ "AudioEventReplaceParam": "belle",
+ "AudioBank": "BK_Belle",
+ "HitTypes": [0],
+ "ElementTypes": [1],
+ "Unk1": 1,
+ "Gender": 2,
+ "Camp": 0,
+ "Unk2": ["1:0:2", "2:1:2"]
+ }
+]
diff --git a/assets/FileCfg/PostGirlConfigTemplateTb.json b/assets/FileCfg/PostGirlConfigTemplateTb.json
new file mode 100644
index 0000000..2891e40
--- /dev/null
+++ b/assets/FileCfg/PostGirlConfigTemplateTb.json
@@ -0,0 +1,194 @@
+[
+ {
+ "ID": 3500000,
+ "Name": "Avatar_Male_Size01_Wise",
+ "MEPLHBONBFE": "2011",
+ "KEGJJDPAKOH": 0,
+ "NOCBKKCNNKA": "30070001",
+ "LDAILPLNAEG": 0,
+ "ABMDGFGEHGF": "IconRole34",
+ "DGJEECKNEJH": [],
+ "FHNMJNDKHLN": "",
+ "NIENEBHOJNP": 0
+ },
+ {
+ "ID": 3500001,
+ "Name": "Avatar_Female_Size02_Belle",
+ "MEPLHBONBFE": "2021",
+ "KEGJJDPAKOH": 0,
+ "NOCBKKCNNKA": "30070001",
+ "LDAILPLNAEG": 0,
+ "ABMDGFGEHGF": "IconRole33",
+ "DGJEECKNEJH": [],
+ "FHNMJNDKHLN": "",
+ "NIENEBHOJNP": 0
+ },
+ {
+ "ID": 3510000,
+ "Name": "Avatar_Female_Size02_Anbi",
+ "MEPLHBONBFE": "1011",
+ "KEGJJDPAKOH": 0,
+ "NOCBKKCNNKA": "1051211000",
+ "LDAILPLNAEG": 0,
+ "ABMDGFGEHGF": "IconRole01",
+ "DGJEECKNEJH": [],
+ "FHNMJNDKHLN": "",
+ "NIENEBHOJNP": 4
+ },
+ {
+ "ID": 3510001,
+ "Name": "Avatar_Female_Size01_Tsubaki",
+ "MEPLHBONBFE": "1021",
+ "KEGJJDPAKOH": 0,
+ "NOCBKKCNNKA": "1051211001",
+ "LDAILPLNAEG": 0,
+ "ABMDGFGEHGF": "IconRole11",
+ "DGJEECKNEJH": [],
+ "FHNMJNDKHLN": "",
+ "NIENEBHOJNP": 4
+ },
+ {
+ "ID": 3510002,
+ "Name": "Avatar_Female_Size02_Nostradamus",
+ "MEPLHBONBFE": "1031",
+ "KEGJJDPAKOH": 0,
+ "NOCBKKCNNKA": "1051211002",
+ "LDAILPLNAEG": 0,
+ "ABMDGFGEHGF": "IconRole12",
+ "DGJEECKNEJH": [],
+ "FHNMJNDKHLN": "",
+ "NIENEBHOJNP": 4
+ },
+ {
+ "ID": 3510003,
+ "Name": "Avatar_Male_Size03_Billy",
+ "MEPLHBONBFE": "1081",
+ "KEGJJDPAKOH": 0,
+ "NOCBKKCNNKA": "1051211003",
+ "LDAILPLNAEG": 0,
+ "ABMDGFGEHGF": "IconRole10",
+ "DGJEECKNEJH": [],
+ "FHNMJNDKHLN": "",
+ "NIENEBHOJNP": 4
+ },
+ {
+ "ID": 3510004,
+ "Name": "Avatar_Female_Size02_Longinus",
+ "MEPLHBONBFE": "1041",
+ "KEGJJDPAKOH": 0,
+ "NOCBKKCNNKA": "1051211004",
+ "LDAILPLNAEG": 0,
+ "ABMDGFGEHGF": "IconRole05",
+ "DGJEECKNEJH": [],
+ "FHNMJNDKHLN": "",
+ "NIENEBHOJNP": 4
+ },
+ {
+ "ID": 3510005,
+ "Name": "Avatar_Female_Size01_OokumaMari",
+ "MEPLHBONBFE": "1101",
+ "KEGJJDPAKOH": 0,
+ "NOCBKKCNNKA": "1051211005",
+ "LDAILPLNAEG": 0,
+ "ABMDGFGEHGF": "IconRole14",
+ "DGJEECKNEJH": [],
+ "FHNMJNDKHLN": "",
+ "NIENEBHOJNP": 4
+ },
+ {
+ "ID": 3510006,
+ "Name": "Avatar_Male_Size03_Ben",
+ "MEPLHBONBFE": "1121",
+ "KEGJJDPAKOH": 0,
+ "NOCBKKCNNKA": "1051211006",
+ "LDAILPLNAEG": 0,
+ "ABMDGFGEHGF": "IconRole16",
+ "DGJEECKNEJH": [],
+ "FHNMJNDKHLN": "",
+ "NIENEBHOJNP": 4
+ },
+ {
+ "ID": 3510007,
+ "Name": "Avatar_Female_Size03_Lisa",
+ "MEPLHBONBFE": "1181",
+ "KEGJJDPAKOH": 0,
+ "NOCBKKCNNKA": "1051211007",
+ "LDAILPLNAEG": 0,
+ "ABMDGFGEHGF": "IconRole20",
+ "DGJEECKNEJH": [],
+ "FHNMJNDKHLN": "",
+ "NIENEBHOJNP": 4
+ },
+ {
+ "ID": 3510008,
+ "Name": "Avatar_Male_Size03_Anton",
+ "MEPLHBONBFE": "1111",
+ "KEGJJDPAKOH": 0,
+ "NOCBKKCNNKA": "1051211008",
+ "LDAILPLNAEG": 0,
+ "ABMDGFGEHGF": "IconRole15",
+ "DGJEECKNEJH": [],
+ "FHNMJNDKHLN": "",
+ "NIENEBHOJNP": 4
+ },
+ {
+ "ID": 3510009,
+ "Name": "Avatar_Male_Size03_Lycaon",
+ "MEPLHBONBFE": "1141",
+ "KEGJJDPAKOH": 0,
+ "NOCBKKCNNKA": "1051211009",
+ "LDAILPLNAEG": 0,
+ "ABMDGFGEHGF": "IconRole18",
+ "DGJEECKNEJH": [],
+ "FHNMJNDKHLN": "",
+ "NIENEBHOJNP": 4
+ },
+ {
+ "ID": 3510010,
+ "Name": "Avatar_Female_Size02_Ellen",
+ "MEPLHBONBFE": "1191",
+ "KEGJJDPAKOH": 0,
+ "NOCBKKCNNKA": "1051211010",
+ "LDAILPLNAEG": 0,
+ "ABMDGFGEHGF": "IconRole21",
+ "DGJEECKNEJH": [],
+ "FHNMJNDKHLN": "",
+ "NIENEBHOJNP": 4
+ },
+ {
+ "ID": 3510011,
+ "Name": "Avatar_Female_Size03_Rina",
+ "MEPLHBONBFE": "1211",
+ "KEGJJDPAKOH": 0,
+ "NOCBKKCNNKA": "1051211011",
+ "LDAILPLNAEG": 0,
+ "ABMDGFGEHGF": "IconRole22",
+ "DGJEECKNEJH": [],
+ "FHNMJNDKHLN": "",
+ "NIENEBHOJNP": 4
+ },
+ {
+ "ID": 3510012,
+ "Name": "Avatar_Female_Size01_Corin",
+ "MEPLHBONBFE": "1061",
+ "KEGJJDPAKOH": 0,
+ "NOCBKKCNNKA": "1051211012",
+ "LDAILPLNAEG": 0,
+ "ABMDGFGEHGF": "IconRole09",
+ "DGJEECKNEJH": [],
+ "FHNMJNDKHLN": "",
+ "NIENEBHOJNP": 4
+ },
+ {
+ "ID": 3510013,
+ "Name": "Avatar_Female_Size03_ZhuYuan",
+ "MEPLHBONBFE": "1241",
+ "KEGJJDPAKOH": 0,
+ "NOCBKKCNNKA": "1051211013",
+ "LDAILPLNAEG": 0,
+ "ABMDGFGEHGF": "IconRole23",
+ "DGJEECKNEJH": [],
+ "FHNMJNDKHLN": "",
+ "NIENEBHOJNP": 4
+ }
+]
diff --git a/assets/FileCfg/ProcedureConfigTemplateTb.json b/assets/FileCfg/ProcedureConfigTemplateTb.json
new file mode 100644
index 0000000..4c0b812
--- /dev/null
+++ b/assets/FileCfg/ProcedureConfigTemplateTb.json
@@ -0,0 +1,50 @@
+[
+ {
+ "ProcedureID": 1,
+ "ProcedureType": 2,
+ "ContentID": "5000008",
+ "JumpTos": [2],
+ "ProcedureBanks": [],
+ "ProcedureEvent": ""
+ },
+ {
+ "ProcedureID": 2,
+ "ProcedureType": 4,
+ "ContentID": "CreateRole/LOGIN_P2_mux.mp4",
+ "JumpTos": [3],
+ "ProcedureBanks": ["BK_C00_CS01", "BK_C00_CS01_VO"],
+ "ProcedureEvent": "Play_C00_CS01_BGM"
+ },
+ {
+ "ProcedureID": 3,
+ "ProcedureType": 2,
+ "ContentID": "5000009",
+ "JumpTos": [4],
+ "ProcedureBanks": [],
+ "ProcedureEvent": ""
+ },
+ {
+ "ProcedureID": 4,
+ "ProcedureType": 1,
+ "ContentID": "107010011",
+ "JumpTos": [5],
+ "ProcedureBanks": [],
+ "ProcedureEvent": ""
+ },
+ {
+ "ProcedureID": 5,
+ "ProcedureType": 1,
+ "ContentID": "107010021",
+ "JumpTos": [6],
+ "ProcedureBanks": [],
+ "ProcedureEvent": ""
+ },
+ {
+ "ProcedureID": 6,
+ "ProcedureType": 1,
+ "ContentID": "107010031",
+ "JumpTos": [],
+ "ProcedureBanks": [],
+ "ProcedureEvent": ""
+ }
+]
diff --git a/assets/FileCfg/SectionConfigTemplateTb.json b/assets/FileCfg/SectionConfigTemplateTb.json
new file mode 100644
index 0000000..d41657b
--- /dev/null
+++ b/assets/FileCfg/SectionConfigTemplateTb.json
@@ -0,0 +1,92 @@
+[
+ {
+ "SectionId": 1,
+ "PhotoName": "Photo_SectionName_01",
+ "Name": "MainCity_Street",
+ "PrimaryEntryName": "Street_PlayerPos_Default",
+ "SecondaryEntryName": "Street_PlayerPos_Default",
+ "ONEGOJKHNJL": 3,
+ "SectionName": "SectionName_Street"
+ },
+ {
+ "SectionId": 2,
+ "PhotoName": "Photo_SectionName_02",
+ "Name": "MainCity_Workshop",
+ "PrimaryEntryName": "Workshop_PlayerPos_Default",
+ "SecondaryEntryName": "Workshop_PlayerPos_Pos2",
+ "ONEGOJKHNJL": 3,
+ "SectionName": "SectionName_Workshop"
+ },
+ {
+ "SectionId": 3,
+ "PhotoName": "Photo_SectionName_03",
+ "Name": "MainCity_Garage",
+ "PrimaryEntryName": "Garage_PlayerPos_Default",
+ "SecondaryEntryName": "Garage_PlayerPos_Default",
+ "ONEGOJKHNJL": 3,
+ "SectionName": "SectionName_Garage"
+ },
+ {
+ "SectionId": 4,
+ "PhotoName": "Photo_SectionName_04",
+ "Name": "MainCity_ConstructionSite",
+ "PrimaryEntryName": "ConstructionSite_PlayerPos_Default",
+ "SecondaryEntryName": "ConstructionSite_PlayerPos_Default",
+ "ONEGOJKHNJL": 3,
+ "SectionName": "SectionName_ConstructionSite"
+ },
+ {
+ "SectionId": 5,
+ "PhotoName": "Photo_SectionName_05",
+ "Name": "MainCity_SkyScraper",
+ "PrimaryEntryName": "SkyScraper_PlayerPos_Default",
+ "SecondaryEntryName": "SkyScraper_PlayerPos_Default",
+ "ONEGOJKHNJL": 3,
+ "SectionName": "SectionName_SkyScraper"
+ },
+ {
+ "SectionId": 101,
+ "PhotoName": "Photo_SectionName_101",
+ "Name": "MainCity_FortuneSquare",
+ "PrimaryEntryName": "FortuneSquare_PlayerPos_Default",
+ "SecondaryEntryName": "FortuneSquare_PlayerPos_Default",
+ "ONEGOJKHNJL": 3,
+ "SectionName": "SectionName_FortuneSquare"
+ },
+ {
+ "SectionId": 103,
+ "PhotoName": "Photo_SectionName_103",
+ "Name": "MainCity_FortuneHIA",
+ "PrimaryEntryName": "FortuneHIA_PlayerPos_Default",
+ "SecondaryEntryName": "FortuneHIA_PlayerPos_Default",
+ "ONEGOJKHNJL": 3,
+ "SectionName": "SectionName_FortuneHIA"
+ },
+ {
+ "SectionId": 151,
+ "PhotoName": "Photo_SectionName_151",
+ "Name": "Maincity_Zero",
+ "PrimaryEntryName": "Zero_PlayerPos_Default",
+ "SecondaryEntryName": "Zero_PlayerPos_Default",
+ "ONEGOJKHNJL": 3,
+ "SectionName": "SectionName_Zero"
+ },
+ {
+ "SectionId": 153,
+ "PhotoName": "Photo_SectionName_153",
+ "Name": "Maincity_Subway_Street",
+ "PrimaryEntryName": "Subway_PlayerPos_Default",
+ "SecondaryEntryName": "Subway_PlayerPos_Default",
+ "ONEGOJKHNJL": 3,
+ "SectionName": "SectionName_Subway"
+ },
+ {
+ "SectionId": 154,
+ "PhotoName": "Photo_SectionName_154",
+ "Name": "Maincity_Subway_FortuneSquare",
+ "PrimaryEntryName": "SubwayFortuneSquare_PlayerPos_Default",
+ "SecondaryEntryName": "SubwayFortuneSquare_PlayerPos_Default",
+ "ONEGOJKHNJL": 3,
+ "SectionName": "SectionName_Subway"
+ }
+]
diff --git a/assets/FileCfg/TrainingQuestTemplateTb.json b/assets/FileCfg/TrainingQuestTemplateTb.json
new file mode 100644
index 0000000..6553da9
--- /dev/null
+++ b/assets/FileCfg/TrainingQuestTemplateTb.json
@@ -0,0 +1,317 @@
+[
+ {
+ "Id": 12254000,
+ "TrainingType": 1,
+ "BattleEventId": 19800014,
+ "CFFJLDMDEML": "",
+ "IIEMNPJFNJD": "",
+ "MEFHKNFOBCL": 0,
+ "PIIKKAIINOM": 0,
+ "CIPGDEMIEMF": 0,
+ "LFLIIIIKBHJ": 0,
+ "HGJGIMKPHLH": false,
+ "OFALKONNAFN": false,
+ "LGGHKLFHOIL": "",
+ "DBIIAEFJHDA": ""
+ },
+ {
+ "Id": 12254001,
+ "TrainingType": 2,
+ "BattleEventId": 19800015,
+ "CFFJLDMDEML": "TrainingRoomTxt_SpecialTraining_Name_1",
+ "IIEMNPJFNJD": "UI/Sprite/A1DynamicLoad/TrainingCourse/UnPacker/TrainingSkill/IconSkill_Evade.png",
+ "MEFHKNFOBCL": 122541011,
+ "PIIKKAIINOM": 122541081,
+ "CIPGDEMIEMF": -1,
+ "LFLIIIIKBHJ": 0,
+ "HGJGIMKPHLH": false,
+ "OFALKONNAFN": false,
+ "LGGHKLFHOIL": "",
+ "DBIIAEFJHDA": ""
+ },
+ {
+ "Id": 12254002,
+ "TrainingType": 2,
+ "BattleEventId": 19800016,
+ "CFFJLDMDEML": "TrainingRoomTxt_SpecialTraining_Name_2",
+ "IIEMNPJFNJD": "UI/Sprite/A1DynamicLoad/TrainingCourse/UnPacker/TrainingSkill/IconSkill_ParryAid.png",
+ "MEFHKNFOBCL": 122541011,
+ "PIIKKAIINOM": 122541081,
+ "CIPGDEMIEMF": 122541021,
+ "LFLIIIIKBHJ": 0,
+ "HGJGIMKPHLH": false,
+ "OFALKONNAFN": false,
+ "LGGHKLFHOIL": "",
+ "DBIIAEFJHDA": ""
+ },
+ {
+ "Id": 12254003,
+ "TrainingType": 2,
+ "BattleEventId": 19800017,
+ "CFFJLDMDEML": "TrainingRoomTxt_SpecialTraining_Name_3",
+ "IIEMNPJFNJD": "UI/Sprite/A1DynamicLoad/TrainingCourse/UnPacker/TrainingSkill/IconSkill_ElementAbnormal.png",
+ "MEFHKNFOBCL": 122541011,
+ "PIIKKAIINOM": 122541081,
+ "CIPGDEMIEMF": -1,
+ "LFLIIIIKBHJ": 0,
+ "HGJGIMKPHLH": false,
+ "OFALKONNAFN": false,
+ "LGGHKLFHOIL": "",
+ "DBIIAEFJHDA": ""
+ },
+ {
+ "Id": 12254004,
+ "TrainingType": 2,
+ "BattleEventId": 19810007,
+ "CFFJLDMDEML": "TrainingRoomTxt_SpecialTraining_Name_4",
+ "IIEMNPJFNJD": "UI/Sprite/A1DynamicLoad/TrainingCourse/UnPacker/TrainingSkill/IconStun.png",
+ "MEFHKNFOBCL": 122541011,
+ "PIIKKAIINOM": 122541081,
+ "CIPGDEMIEMF": 122541031,
+ "LFLIIIIKBHJ": 0,
+ "HGJGIMKPHLH": false,
+ "OFALKONNAFN": false,
+ "LGGHKLFHOIL": "UI/Sprite/A1DynamicLoad/IconRoleCircle/UnPacker/IconRoleCircle01.png",
+ "DBIIAEFJHDA": ""
+ },
+ {
+ "Id": 12254005,
+ "TrainingType": 2,
+ "BattleEventId": 19810008,
+ "CFFJLDMDEML": "TrainingRoomTxt_SpecialTraining_Name_5",
+ "IIEMNPJFNJD": "UI/Sprite/A1DynamicLoad/TrainingCourse/UnPacker/TrainingSkill/IconAttack.png",
+ "MEFHKNFOBCL": 122541081,
+ "PIIKKAIINOM": 122541011,
+ "CIPGDEMIEMF": 122541031,
+ "LFLIIIIKBHJ": 0,
+ "HGJGIMKPHLH": false,
+ "OFALKONNAFN": false,
+ "LGGHKLFHOIL": "UI/Sprite/A1DynamicLoad/IconRoleCircle/UnPacker/IconRoleCircle10.png",
+ "DBIIAEFJHDA": ""
+ },
+ {
+ "Id": 12254006,
+ "TrainingType": 2,
+ "BattleEventId": 19810001,
+ "CFFJLDMDEML": "TrainingRoomTxt_SpecialTraining_Name_6",
+ "IIEMNPJFNJD": "UI/Sprite/A1DynamicLoad/TrainingCourse/UnPacker/TrainingSkill/IconSupport.png",
+ "MEFHKNFOBCL": 122541031,
+ "PIIKKAIINOM": 122541081,
+ "CIPGDEMIEMF": 122541061,
+ "LFLIIIIKBHJ": 0,
+ "HGJGIMKPHLH": false,
+ "OFALKONNAFN": false,
+ "LGGHKLFHOIL": "UI/Sprite/A1DynamicLoad/IconRoleCircle/UnPacker/IconRoleCircle12.png",
+ "DBIIAEFJHDA": ""
+ },
+ {
+ "Id": 12254007,
+ "TrainingType": 2,
+ "BattleEventId": 19810009,
+ "CFFJLDMDEML": "TrainingRoomTxt_SpecialTraining_Name_7",
+ "IIEMNPJFNJD": "UI/Sprite/A1DynamicLoad/TrainingCourse/UnPacker/TrainingSkill/IconAttack.png",
+ "MEFHKNFOBCL": 122541021,
+ "PIIKKAIINOM": 122541281,
+ "CIPGDEMIEMF": 122541011,
+ "LFLIIIIKBHJ": 0,
+ "HGJGIMKPHLH": false,
+ "OFALKONNAFN": false,
+ "LGGHKLFHOIL": "UI/Sprite/A1DynamicLoad/IconRoleCircle/UnPacker/IconRoleCircle11.png",
+ "DBIIAEFJHDA": ""
+ },
+ {
+ "Id": 12254008,
+ "TrainingType": 2,
+ "BattleEventId": 19810011,
+ "CFFJLDMDEML": "TrainingRoomTxt_SpecialTraining_Name_8",
+ "IIEMNPJFNJD": "UI/Sprite/A1DynamicLoad/TrainingCourse/UnPacker/TrainingSkill/IconStun.png",
+ "MEFHKNFOBCL": 122541101,
+ "PIIKKAIINOM": 122541121,
+ "CIPGDEMIEMF": 122541111,
+ "LFLIIIIKBHJ": 0,
+ "HGJGIMKPHLH": false,
+ "OFALKONNAFN": false,
+ "LGGHKLFHOIL": "UI/Sprite/A1DynamicLoad/IconRoleCircle/UnPacker/IconRoleCircle14.png",
+ "DBIIAEFJHDA": ""
+ },
+ {
+ "Id": 12254009,
+ "TrainingType": 2,
+ "BattleEventId": 19810002,
+ "CFFJLDMDEML": "TrainingRoomTxt_SpecialTraining_Name_9",
+ "IIEMNPJFNJD": "UI/Sprite/A1DynamicLoad/TrainingCourse/UnPacker/TrainingSkill/IconDefense.png",
+ "MEFHKNFOBCL": 122541121,
+ "PIIKKAIINOM": 122541111,
+ "CIPGDEMIEMF": 122541011,
+ "LFLIIIIKBHJ": 0,
+ "HGJGIMKPHLH": false,
+ "OFALKONNAFN": false,
+ "LGGHKLFHOIL": "UI/Sprite/A1DynamicLoad/IconRoleCircle/UnPacker/IconRoleCircle16.png",
+ "DBIIAEFJHDA": ""
+ },
+ {
+ "Id": 12254010,
+ "TrainingType": 2,
+ "BattleEventId": 19810010,
+ "CFFJLDMDEML": "TrainingRoomTxt_SpecialTraining_Name_10",
+ "IIEMNPJFNJD": "UI/Sprite/A1DynamicLoad/TrainingCourse/UnPacker/TrainingSkill/IconAnomaly.png",
+ "MEFHKNFOBCL": 122541181,
+ "PIIKKAIINOM": 122541031,
+ "CIPGDEMIEMF": 122541111,
+ "LFLIIIIKBHJ": 0,
+ "HGJGIMKPHLH": false,
+ "OFALKONNAFN": false,
+ "LGGHKLFHOIL": "UI/Sprite/A1DynamicLoad/IconRoleCircle/UnPacker/IconRoleCircle20.png",
+ "DBIIAEFJHDA": ""
+ },
+ {
+ "Id": 12254011,
+ "TrainingType": 2,
+ "BattleEventId": 19810006,
+ "CFFJLDMDEML": "TrainingRoomTxt_SpecialTraining_Name_11",
+ "IIEMNPJFNJD": "UI/Sprite/A1DynamicLoad/TrainingCourse/UnPacker/TrainingSkill/IconAttack.png",
+ "MEFHKNFOBCL": 122541111,
+ "PIIKKAIINOM": 122541011,
+ "CIPGDEMIEMF": 122541121,
+ "LFLIIIIKBHJ": 0,
+ "HGJGIMKPHLH": false,
+ "OFALKONNAFN": false,
+ "LGGHKLFHOIL": "UI/Sprite/A1DynamicLoad/IconRoleCircle/UnPacker/IconRoleCircle15.png",
+ "DBIIAEFJHDA": ""
+ },
+ {
+ "Id": 12254012,
+ "TrainingType": 2,
+ "BattleEventId": 19810012,
+ "CFFJLDMDEML": "TrainingRoomTxt_SpecialTraining_Name_12",
+ "IIEMNPJFNJD": "UI/Sprite/A1DynamicLoad/TrainingCourse/UnPacker/TrainingSkill/IconStun.png",
+ "MEFHKNFOBCL": 122541141,
+ "PIIKKAIINOM": 122541061,
+ "CIPGDEMIEMF": 122541031,
+ "LFLIIIIKBHJ": 0,
+ "HGJGIMKPHLH": false,
+ "OFALKONNAFN": false,
+ "LGGHKLFHOIL": "UI/Sprite/A1DynamicLoad/IconRoleCircle/UnPacker/IconRoleCircle18.png",
+ "DBIIAEFJHDA": ""
+ },
+ {
+ "Id": 12254013,
+ "TrainingType": 2,
+ "BattleEventId": 19810003,
+ "CFFJLDMDEML": "TrainingRoomTxt_SpecialTraining_Name_13",
+ "IIEMNPJFNJD": "UI/Sprite/A1DynamicLoad/TrainingCourse/UnPacker/TrainingSkill/IconAttack.png",
+ "MEFHKNFOBCL": 122541191,
+ "PIIKKAIINOM": 122541011,
+ "CIPGDEMIEMF": 122541131,
+ "LFLIIIIKBHJ": 0,
+ "HGJGIMKPHLH": false,
+ "OFALKONNAFN": false,
+ "LGGHKLFHOIL": "UI/Sprite/A1DynamicLoad/IconRoleCircle/UnPacker/IconRoleCircle21.png",
+ "DBIIAEFJHDA": ""
+ },
+ {
+ "Id": 12254014,
+ "TrainingType": 2,
+ "BattleEventId": 19810013,
+ "CFFJLDMDEML": "TrainingRoomTxt_SpecialTraining_Name_14",
+ "IIEMNPJFNJD": "UI/Sprite/A1DynamicLoad/TrainingCourse/UnPacker/TrainingSkill/IconSupport.png",
+ "MEFHKNFOBCL": 122541211,
+ "PIIKKAIINOM": 122541011,
+ "CIPGDEMIEMF": 122541111,
+ "LFLIIIIKBHJ": 0,
+ "HGJGIMKPHLH": false,
+ "OFALKONNAFN": false,
+ "LGGHKLFHOIL": "UI/Sprite/A1DynamicLoad/IconRoleCircle/UnPacker/IconRoleCircle22.png",
+ "DBIIAEFJHDA": ""
+ },
+ {
+ "Id": 12254015,
+ "TrainingType": 2,
+ "BattleEventId": 19810014,
+ "CFFJLDMDEML": "TrainingRoomTxt_SpecialTraining_Name_15",
+ "IIEMNPJFNJD": "UI/Sprite/A1DynamicLoad/TrainingCourse/UnPacker/TrainingSkill/IconAttack.png",
+ "MEFHKNFOBCL": 122541061,
+ "PIIKKAIINOM": 122541011,
+ "CIPGDEMIEMF": 122541081,
+ "LFLIIIIKBHJ": 0,
+ "HGJGIMKPHLH": false,
+ "OFALKONNAFN": false,
+ "LGGHKLFHOIL": "UI/Sprite/A1DynamicLoad/IconRoleCircle/UnPacker/IconRoleCircle09.png",
+ "DBIIAEFJHDA": ""
+ },
+ {
+ "Id": 12254016,
+ "TrainingType": 2,
+ "BattleEventId": 19810015,
+ "CFFJLDMDEML": "TrainingRoomTxt_SpecialTraining_Name_16",
+ "IIEMNPJFNJD": "UI/Sprite/A1DynamicLoad/TrainingCourse/UnPacker/TrainingSkill/IconAttack.png",
+ "MEFHKNFOBCL": 122541041,
+ "PIIKKAIINOM": 122541011,
+ "CIPGDEMIEMF": 122541121,
+ "LFLIIIIKBHJ": 0,
+ "HGJGIMKPHLH": false,
+ "OFALKONNAFN": false,
+ "LGGHKLFHOIL": "UI/Sprite/A1DynamicLoad/IconRoleCircle/UnPacker/IconRoleCircle05.png",
+ "DBIIAEFJHDA": ""
+ },
+ {
+ "Id": 12254017,
+ "TrainingType": 2,
+ "BattleEventId": 19810004,
+ "CFFJLDMDEML": "TrainingRoomTxt_SpecialTraining_Name_17",
+ "IIEMNPJFNJD": "UI/Sprite/A1DynamicLoad/TrainingCourse/UnPacker/TrainingSkill/IconAttack.png",
+ "MEFHKNFOBCL": 122541241,
+ "PIIKKAIINOM": 122541011,
+ "CIPGDEMIEMF": 122541031,
+ "LFLIIIIKBHJ": 0,
+ "HGJGIMKPHLH": false,
+ "OFALKONNAFN": false,
+ "LGGHKLFHOIL": "UI/Sprite/A1DynamicLoad/IconRoleCircle/UnPacker/IconRoleCircle23.png",
+ "DBIIAEFJHDA": "zhuyuan_release"
+ },
+ {
+ "Id": 12254018,
+ "TrainingType": 2,
+ "BattleEventId": 19810005,
+ "CFFJLDMDEML": "TrainingRoomTxt_SpecialTraining_Name_18",
+ "IIEMNPJFNJD": "UI/Sprite/A1DynamicLoad/TrainingCourse/UnPacker/TrainingSkill/IconSupport.png",
+ "MEFHKNFOBCL": 122541131,
+ "PIIKKAIINOM": 122541081,
+ "CIPGDEMIEMF": 122541061,
+ "LFLIIIIKBHJ": 0,
+ "HGJGIMKPHLH": false,
+ "OFALKONNAFN": false,
+ "LGGHKLFHOIL": "UI/Sprite/A1DynamicLoad/IconRoleCircle/UnPacker/IconRoleCircle17.png",
+ "DBIIAEFJHDA": ""
+ },
+ {
+ "Id": 12254019,
+ "TrainingType": 2,
+ "BattleEventId": 19810016,
+ "CFFJLDMDEML": "TrainingRoomTxt_SpecialTraining_Name_19",
+ "IIEMNPJFNJD": "UI/Sprite/A1DynamicLoad/TrainingCourse/UnPacker/TrainingSkill/IconSupport.png",
+ "MEFHKNFOBCL": 122541151,
+ "PIIKKAIINOM": 122541081,
+ "CIPGDEMIEMF": 122541121,
+ "LFLIIIIKBHJ": 0,
+ "HGJGIMKPHLH": false,
+ "OFALKONNAFN": false,
+ "LGGHKLFHOIL": "UI/Sprite/A1DynamicLoad/IconRoleCircle/UnPacker/IconRoleCircle27.png",
+ "DBIIAEFJHDA": ""
+ },
+ {
+ "Id": 12254021,
+ "TrainingType": 2,
+ "BattleEventId": 19810018,
+ "CFFJLDMDEML": "TrainingRoomTxt_SpecialTraining_Name_21",
+ "IIEMNPJFNJD": "UI/Sprite/A1DynamicLoad/TrainingCourse/UnPacker/TrainingSkill/IconAnomaly.png",
+ "MEFHKNFOBCL": 122541281,
+ "PIIKKAIINOM": 122541081,
+ "CIPGDEMIEMF": 122541151,
+ "LFLIIIIKBHJ": 0,
+ "HGJGIMKPHLH": false,
+ "OFALKONNAFN": false,
+ "LGGHKLFHOIL": "UI/Sprite/A1DynamicLoad/IconRoleCircle/UnPacker/IconRoleCircle28.png",
+ "DBIIAEFJHDA": ""
+ }
+]
diff --git a/assets/FileCfg/UnlockConfigTemplateTb.json b/assets/FileCfg/UnlockConfigTemplateTb.json
new file mode 100644
index 0000000..f9a88a1
--- /dev/null
+++ b/assets/FileCfg/UnlockConfigTemplateTb.json
@@ -0,0 +1,3360 @@
+[
+ {
+ "ID": 1001,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 1,
+ "ENAFENAEECG": 1,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/MainCityMenus/Packer/IconSundryBtn.png",
+ "JAKDPIDICCJ": 0,
+ "Name": "UIText_321",
+ "BOMNEKHOGIH": "UI/Sprite/MainCityMenus/Packer/IconSundryBtn.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1002,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 2,
+ "ENAFENAEECG": 1,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 1,
+ "HCLOAOMNJEA": "GachaText_UnlockHint",
+ "IconRes": "UI/Sprite/MainCityMenus/Packer/IconGashaponBtn.png",
+ "JAKDPIDICCJ": 4,
+ "Name": "Gacha_Button_Entrance",
+ "BOMNEKHOGIH": "UI/Sprite/MainCityMenus/Packer/IconGashaponBtn.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1003,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 3,
+ "ENAFENAEECG": 1,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/MainCityMenus/Packer/IconShopBtn02.png",
+ "JAKDPIDICCJ": 0,
+ "Name": "UIText_323",
+ "BOMNEKHOGIH": "UI/Sprite/MainCityMenus/Packer/IconShopBtn02.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1004,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 1,
+ "HCLOAOMNJEA": "GachaText_Bangboo_UnlockHint",
+ "IconRes": "UI/Sprite/MainCityMenus/Packer/IconGashaponBtn.png",
+ "JAKDPIDICCJ": 0,
+ "Name": "TabText_4001",
+ "BOMNEKHOGIH": "UI/Sprite/MainCityMenus/Packer/IconGashaponBtn.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1005,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 5,
+ "ENAFENAEECG": 1,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/MainCityMenus/Packer/IconYorozuyaManualBtn.png",
+ "JAKDPIDICCJ": 25,
+ "Name": "UIText_325",
+ "BOMNEKHOGIH": "UI/Sprite/MainCityMenus/Packer/IconYorozuyaManualBtn.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1006,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 6,
+ "ENAFENAEECG": 1,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/MainCityMenus/Packer/IconBagBtn.png",
+ "JAKDPIDICCJ": 0,
+ "Name": "UIText_326",
+ "BOMNEKHOGIH": "UI/Sprite/MainCityMenus/Packer/IconBagBtn.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1007,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 7,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/MainCityMenus/Packer/IconBangBooBtn.png",
+ "JAKDPIDICCJ": 9,
+ "Name": "UIText_327",
+ "BOMNEKHOGIH": "UI/Sprite/MainCityMenus/Packer/IconBangBooBtn.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1008,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 8,
+ "ENAFENAEECG": 1,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/MainCityMenus/Packer/IconRoleBtn02.png",
+ "JAKDPIDICCJ": 7,
+ "Name": "UIText_328",
+ "BOMNEKHOGIH": "UI/Sprite/MainCityMenus/Packer/IconRoleBtn02.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1009,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/MainCityMenus/Packer/IconTeleportBtn.png",
+ "JAKDPIDICCJ": 28,
+ "Name": "UIText_329",
+ "BOMNEKHOGIH": "UI/Sprite/MainCityMenus/Packer/IconTeleportBtn.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1010,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 10,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 11,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1011,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 11,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": "MenuText_LockHint",
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": "MenuText_UnlockHint",
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1013,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 12,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1014,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 14,
+ "ENAFENAEECG": 1,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/MainCityMenus/Packer/IconSetUp.png",
+ "JAKDPIDICCJ": 0,
+ "Name": "UIText_330",
+ "BOMNEKHOGIH": "UI/Sprite/MainCityMenus/Packer/IconSetUp.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1015,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 214,
+ "ENAFENAEECG": 2,
+ "ELOHGFJOJBM": 2,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/A1DynamicLoad/IconMenusOption/Packer/IconMail.png",
+ "JAKDPIDICCJ": 2,
+ "Name": "UIText_331",
+ "BOMNEKHOGIH": "UI/Sprite/A1DynamicLoad/IconMenusOption/Packer/IconMail.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 1,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1016,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 215,
+ "ENAFENAEECG": 2,
+ "ELOHGFJOJBM": 2,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/A1DynamicLoad/IconMenusOption/Packer/IconNotice.png",
+ "JAKDPIDICCJ": 26,
+ "Name": "UIText_332",
+ "BOMNEKHOGIH": "UI/Sprite/A1DynamicLoad/IconMenusOption/Packer/IconNotice.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 1,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1017,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 217,
+ "ENAFENAEECG": 2,
+ "ELOHGFJOJBM": 2,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/A1DynamicLoad/IconMenusOption/Packer/IconFeedback.png",
+ "JAKDPIDICCJ": 3,
+ "Name": "UIText_354",
+ "BOMNEKHOGIH": "UI/Sprite/A1DynamicLoad/IconMenusOption/Packer/IconFeedback.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 1,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1018,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 18,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": "HollowPause_LockHint",
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1019,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 220,
+ "ENAFENAEECG": 2,
+ "ELOHGFJOJBM": 2,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/A1DynamicLoad/IconMenusOption/Packer/IconSignOut",
+ "JAKDPIDICCJ": 0,
+ "Name": "UIText_367",
+ "BOMNEKHOGIH": "UI/Sprite/A1DynamicLoad/IconMenusOption/Packer/IconSignOut",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1020,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 20,
+ "ENAFENAEECG": 3,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 1,
+ "HCLOAOMNJEA": "Activity_UnlockHint",
+ "IconRes": null,
+ "JAKDPIDICCJ": 5,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1021,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/MainCityMenus/Packer/IconPhotograph.png",
+ "JAKDPIDICCJ": 0,
+ "Name": "UIText_582",
+ "BOMNEKHOGIH": "UI/Sprite/MainCityMenus/Packer/IconPhotograph.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1022,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 21,
+ "ENAFENAEECG": 1,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/MainCityMenus/Packer/IconMsgBtn.png",
+ "JAKDPIDICCJ": 27,
+ "Name": "UIText_568",
+ "BOMNEKHOGIH": "UI/Sprite/MainCityMenus/Packer/IconMsgBtn.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1023,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 2,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/MainCityMenus/Packer/IconTrainingCourseBtn.png",
+ "JAKDPIDICCJ": 0,
+ "Name": "UIText_569",
+ "BOMNEKHOGIH": "UI/Sprite/A1DynamicLoad/KeyIcon/Packer/TestIcon.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [1012]
+ },
+ {
+ "ID": 1024,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 8,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1025,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 1,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1026,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 10,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1027,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 15,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1028,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 16,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1029,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 17,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1030,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 18,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1031,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 19,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1032,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 21,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 1,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [1001]
+ },
+ {
+ "ID": 1033,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 23,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [1002]
+ },
+ {
+ "ID": 1034,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 27,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1035,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 29,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1036,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 1,
+ "HCLOAOMNJEA": "BangbooModify_UnlockHint",
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1037,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 242,
+ "ENAFENAEECG": 2,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/A1DynamicLoad/IconMenusOption/Packer/IconSeparate.png",
+ "JAKDPIDICCJ": 0,
+ "Name": "UIText_702",
+ "BOMNEKHOGIH": "UI/Sprite/A1DynamicLoad/IconMenusOption/Packer/IconFeedback.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1038,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 4,
+ "ENAFENAEECG": 1,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": "Bp_Unlock_ItemUse_Tips",
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/MainCityMenus/Packer/IconShopBtn02.png",
+ "JAKDPIDICCJ": 0,
+ "Name": "UIText_747",
+ "BOMNEKHOGIH": "UI/Sprite/MainCityMenus/Packer/IconShopBtn02.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1040,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 23,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [102201]
+ },
+ {
+ "ID": 1041,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 218,
+ "ENAFENAEECG": 2,
+ "ELOHGFJOJBM": 2,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/A1DynamicLoad/IconMenusOption/Packer/IconCommunity.png",
+ "JAKDPIDICCJ": 46,
+ "Name": "UIText_762",
+ "BOMNEKHOGIH": "UI/Sprite/A1DynamicLoad/IconMenusOption/Packer/IconCommunity.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 1,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1042,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 221,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "UIText_762",
+ "BOMNEKHOGIH": "UI/Sprite/A1DynamicLoad/IconMenusOption/Packer/IconCommunity.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1043,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1044,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 222,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 2,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/A1DynamicLoad/IconMenusOption/Packer/IconBackWall.png",
+ "JAKDPIDICCJ": 0,
+ "Name": "UIText_855",
+ "BOMNEKHOGIH": "UI/Sprite/A1DynamicLoad/IconMenusOption/Packer/IconBackWall.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1045,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1046,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 219,
+ "ENAFENAEECG": 2,
+ "ELOHGFJOJBM": 2,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/A1DynamicLoad/IconMenusOption/Packer/IconPGC.png",
+ "JAKDPIDICCJ": 44,
+ "Name": "UIText_PGCentrance",
+ "BOMNEKHOGIH": "UI/Sprite/A1DynamicLoad/IconMenusOption/Packer/IconPGC.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 1,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1048,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 23,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [102101]
+ },
+ {
+ "ID": 1049,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1050,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 223,
+ "ENAFENAEECG": 2,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "Assets/NapResources/UI/Sprite/A1DynamicLoad/IconMenusOption/Packer/IconRedeemCode.png",
+ "JAKDPIDICCJ": 52,
+ "Name": "UIText_RedeemCodeTitle",
+ "BOMNEKHOGIH": "Assets/NapResources/UI/Sprite/A1DynamicLoad/IconMenusOption/Packer/IconRedeemCode.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 1,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1051,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1052,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1053,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 2,
+ "MLNDMLPDLKP": "TeleportJumpFailedInfo_CharacterQuest",
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1054,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 62,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 1,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1055,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 63,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 1,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1056,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 61,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 1,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1057,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 64,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 1,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1058,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 54,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 1,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1059,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 55,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 1,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1060,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 2,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/MainCityMenus/Packer/IconRopemakerNoteBtn.png",
+ "JAKDPIDICCJ": 0,
+ "Name": "UIText_514",
+ "BOMNEKHOGIH": "UI/Sprite/MainCityMenus/Packer/IconRopemakerNoteBtn.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 0,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 1061,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 5,
+ "ENAFENAEECG": 1,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/MainCityMenus/Packer/IconYorozuyaManualBtn.png",
+ "JAKDPIDICCJ": 25,
+ "Name": "UIText_325",
+ "BOMNEKHOGIH": "UI/Sprite/MainCityMenus/Packer/IconYorozuyaManualBtn.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 2000,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 2001,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 3000,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 3001,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10001,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 23,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10002,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 24,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 4,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10003,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 25,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10005,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 27,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10006,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 28,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": "InventoryText_LockHint",
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": "InventoryText_UnlockHint",
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10007,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 29,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10008,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 30,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10009,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 31,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": "Teleport_UnlockHint",
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10010,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 32,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": "SmithyText_LockHint",
+ "KEGJJDPAKOH": 1,
+ "HCLOAOMNJEA": "SmithyText_UnlockHint",
+ "IconRes": null,
+ "JAKDPIDICCJ": 11,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [1003]
+ },
+ {
+ "ID": 10012,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 33,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": "RamenText_LockHint",
+ "KEGJJDPAKOH": 1,
+ "HCLOAOMNJEA": "RamenText_UnlockHint",
+ "IconRes": null,
+ "JAKDPIDICCJ": 14,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [2019, 41120101]
+ },
+ {
+ "ID": 10013,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 34,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": "WorkbenchText_LockHint",
+ "KEGJJDPAKOH": 1,
+ "HCLOAOMNJEA": "WorkbenchText_UnlockHint",
+ "IconRes": null,
+ "JAKDPIDICCJ": 20,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [1005]
+ },
+ {
+ "ID": 10014,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 35,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": "VHSStoreText_LockHint",
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": "VHSStoreText_UnlockHint",
+ "IconRes": null,
+ "JAKDPIDICCJ": 13,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [2028]
+ },
+ {
+ "ID": 10015,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 36,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": "GroceryText_LockHint",
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": "GroceryText_UnlockHint",
+ "IconRes": null,
+ "JAKDPIDICCJ": 12,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10017,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 37,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10018,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 38,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 1,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [1001]
+ },
+ {
+ "ID": 10019,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 39,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10020,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 40,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 1,
+ "HCLOAOMNJEA": "FortuneHIA_UnlockHint",
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10021,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 41,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": "VRText_UnlockHint",
+ "IconRes": null,
+ "JAKDPIDICCJ": 24,
+ "Name": "UIText_465",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [103201]
+ },
+ {
+ "ID": 10022,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [100901]
+ },
+ {
+ "ID": 10023,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10024,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 2,
+ "AFJAEFJFGOD": "ArcadeAchievement_LockHint",
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10025,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 1,
+ "HCLOAOMNJEA": "ArcadeText_UnlockHint",
+ "IconRes": null,
+ "JAKDPIDICCJ": 15,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [1008]
+ },
+ {
+ "ID": 10026,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 1,
+ "HCLOAOMNJEA": "CafeText_UnlockHint",
+ "IconRes": null,
+ "JAKDPIDICCJ": 17,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [1009, 41120301]
+ },
+ {
+ "ID": 10027,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": "TrendyText_UnlockHint",
+ "IconRes": null,
+ "JAKDPIDICCJ": 16,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10028,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 1,
+ "HCLOAOMNJEA": "BangbooModText_UnlockHint",
+ "IconRes": null,
+ "JAKDPIDICCJ": 10,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [1011]
+ },
+ {
+ "ID": 10029,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": "NewsstandText_UnlockHint",
+ "IconRes": null,
+ "JAKDPIDICCJ": 19,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [2099, 41120401]
+ },
+ {
+ "ID": 10030,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [100401]
+ },
+ {
+ "ID": 10031,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [10011]
+ },
+ {
+ "ID": 10032,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 18,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 1,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10033,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10034,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10035,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 38,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10036,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [100901]
+ },
+ {
+ "ID": 10037,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 22,
+ "ENAFENAEECG": 1,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 1,
+ "HCLOAOMNJEA": "Handbook_UnlockHint",
+ "IconRes": "UI/Sprite/MainCityMenus/Packer/IconHandBookBtn.png",
+ "JAKDPIDICCJ": 0,
+ "Name": "HB_HandbookName",
+ "BOMNEKHOGIH": "UI/Sprite/MainCityMenus/Packer/IconHandBookBtn.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10038,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10039,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 2,
+ "AFJAEFJFGOD": "AbyssText_RewardBar_LockedDes",
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10040,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 2,
+ "AFJAEFJFGOD": "AbyssText_PeriodicDuty_LockedDes",
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10041,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 2,
+ "AFJAEFJFGOD": "AbyssText_Talent_LockedDes",
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10042,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10043,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [602001, 602004]
+ },
+ {
+ "ID": 10044,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10045,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [1002]
+ },
+ {
+ "ID": 10046,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [1005]
+ },
+ {
+ "ID": 10047,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [1005]
+ },
+ {
+ "ID": 10048,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 2,
+ "AFJAEFJFGOD": "AbyssText_PlayMethod201_UnlockTips",
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10049,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10050,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10051,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [102202]
+ },
+ {
+ "ID": 10052,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10053,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10054,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10055,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10056,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10057,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10058,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10059,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10060,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10061,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 10062,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [102601]
+ },
+ {
+ "ID": 10063,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [102302]
+ },
+ {
+ "ID": 10064,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [102102]
+ },
+ {
+ "ID": 10065,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [103101]
+ },
+ {
+ "ID": 10066,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [102601]
+ },
+ {
+ "ID": 20001,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/A1DynamicLoad/MainCityRevival/UnPacker/MainCityRevivalBanner01.png",
+ "JAKDPIDICCJ": 22,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 2,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [215605]
+ },
+ {
+ "ID": 20002,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/A1DynamicLoad/MainCityRevival/UnPacker/MainCityRevivalBanner03.png",
+ "JAKDPIDICCJ": 22,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 2,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [2232]
+ },
+ {
+ "ID": 20003,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [104201]
+ },
+ {
+ "ID": 20004,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [104202]
+ },
+ {
+ "ID": 20005,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [104205]
+ },
+ {
+ "ID": 20006,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [104206]
+ },
+ {
+ "ID": 20007,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [104201]
+ },
+ {
+ "ID": 20008,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [104206]
+ },
+ {
+ "ID": 30001,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 1,
+ "HCLOAOMNJEA": "VHSText_UnlockHint",
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 30002,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 30003,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 42,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": [1012]
+ },
+ {
+ "ID": 30004,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 43,
+ "ENAFENAEECG": 1,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": "UI/Sprite/MainCityMenus/Packer/IconBagBtn.png",
+ "JAKDPIDICCJ": 0,
+ "Name": "UIText_326",
+ "BOMNEKHOGIH": "UI/Sprite/MainCityMenus/Packer/IconBagBtn.png",
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 30005,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 1,
+ "HCLOAOMNJEA": "DirectoryText_UnlockHint",
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 0,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 30011,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 1,
+ "JIMLEDBLDAB": 6,
+ "FNLCGMPPJKH": true,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 30013,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 1,
+ "JIMLEDBLDAB": 6,
+ "FNLCGMPPJKH": true,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 30101,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 90001,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 90002,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 90003,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 90004,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ },
+ {
+ "ID": 90005,
+ "NOCBKKCNNKA": 0,
+ "Unk1": 0,
+ "MDBIECECHIC": 0,
+ "ENAFENAEECG": 0,
+ "ELOHGFJOJBM": 1,
+ "AFJAEFJFGOD": null,
+ "KEGJJDPAKOH": 0,
+ "HCLOAOMNJEA": null,
+ "IconRes": null,
+ "JAKDPIDICCJ": 0,
+ "Name": "",
+ "BOMNEKHOGIH": null,
+ "IBIFHFJMHFF": 0,
+ "JIMLEDBLDAB": 7,
+ "FNLCGMPPJKH": false,
+ "IFKMACGPKKE": 0,
+ "MLNDMLPDLKP": null,
+ "EKONEAMOOMJ": 0,
+ "CPHCIFOKPJF": null,
+ "NGPMOECOMFO": []
+ }
+]
diff --git a/assets/VideoUSMEncKeys.json b/assets/VideoUSMEncKeys.json
new file mode 100644
index 0000000..9862a8b
--- /dev/null
+++ b/assets/VideoUSMEncKeys.json
@@ -0,0 +1,1446 @@
+{
+ "1112": 12607812593599203650,
+ "1414": 2255670086296318655,
+ "1149": 6768623875946993255,
+ "755": 2240505932829562479,
+ "876": 14537151291232041107,
+ "39": 1679047787191326358,
+ "503": 47758041908824725,
+ "923": 1488749794054503151,
+ "974": 16834888143726021766,
+ "510": 12981987091208375878,
+ "540": 135271017656796591,
+ "168": 14167915798024595147,
+ "115": 6984288773652347096,
+ "656": 11439106856529408288,
+ "1175": 9636733358420316009,
+ "1347": 203706590790681835,
+ "153": 3881529259453143208,
+ "801": 4220037440218063553,
+ "1248": 15762513372261491596,
+ "279": 9410861914139312908,
+ "1235": 14479830211791913213,
+ "120": 1469915053475756,
+ "30": 789894796995985676,
+ "871": 2970340705250315181,
+ "268": 17422824506356232561,
+ "881": 886762534749491546,
+ "1049": 13030774252870594077,
+ "1075": 5192216743473408164,
+ "1172": 4696712609906101423,
+ "673": 13081025441433850269,
+ "942": 7628955482663819092,
+ "757": 12258579383281318956,
+ "456": 1823003704577139134,
+ "743": 14899926117221588668,
+ "894": 16987096150156468248,
+ "325": 3459758145434381927,
+ "1161": 3562202675000187163,
+ "273": 13792454828578330274,
+ "929": 2670021902775165679,
+ "110": 17656479978965435929,
+ "767": 2391291851017441567,
+ "796": 6973539008594550429,
+ "517": 1818394380248172854,
+ "1236": 12241219660263808557,
+ "1363": 15291646704984970310,
+ "670": 12895009080170563985,
+ "667": 2050540642086953894,
+ "967": 174880871348403812,
+ "637": 4171923603679167240,
+ "29": 1499431651345682031,
+ "298": 7557180876959290425,
+ "1320": 5364583215949898332,
+ "1288": 1698982710206032896,
+ "820": 14730723311732531084,
+ "827": 9885313787174415709,
+ "1102": 11069595631927836480,
+ "1041": 14720601539004134839,
+ "1045": 3070812810340221239,
+ "782": 14523121178286768223,
+ "883": 17668574265751795961,
+ "661": 15085369160732983010,
+ "463": 9867670124233366274,
+ "551": 17922124621771548793,
+ "1154": 5505144612025424571,
+ "785": 1143375444467609792,
+ "204": 13043837640269054066,
+ "118": 11426879884820415074,
+ "212": 16904123080689623432,
+ "460": 2169093733730144742,
+ "627": 13533646100088833239,
+ "1224": 3002064946368460661,
+ "1056": 18306425786552295282,
+ "808": 1940706174300159470,
+ "42": 6119469082135650634,
+ "858": 10960635186213064528,
+ "392": 7097010738201853596,
+ "1318": 16805103495294893379,
+ "908": 14053286907958215039,
+ "1225": 15394227139545206772,
+ "888": 52351487249802958,
+ "1253": 10358556700669426826,
+ "1216": 843589937872556860,
+ "587": 14127223665339335344,
+ "23": 8897500757367027013,
+ "658": 15239203979341755659,
+ "445": 16629305914159167072,
+ "100": 15079928251529886336,
+ "1262": 18183698807051095076,
+ "444": 13447157740977355927,
+ "22": 16763867666844196189,
+ "853": 6986791367444866133,
+ "40": 8064464084291537306,
+ "1181": 176672758750476320,
+ "991": 2365816802524057377,
+ "1472": 15785755811873428448,
+ "581": 9458818600367564703,
+ "1066": 9268668021128799661,
+ "1413": 16872677136836937580,
+ "1438": 7998722160224771924,
+ "1219": 8785591418842088592,
+ "980": 15099083933771166190,
+ "72": 18380512730448539585,
+ "677": 6686780069622603030,
+ "1005": 14187940573262774229,
+ "249": 14330257876875956315,
+ "1184": 16705679165625706293,
+ "493": 13284533546666013807,
+ "1416": 1706830207296453895,
+ "1033": 1988028311028780466,
+ "250": 5672874661338629666,
+ "919": 11171110403428499289,
+ "1376": 15668386760529382008,
+ "461": 14069502027371350634,
+ "603": 8451021713105456929,
+ "839": 368929684669666391,
+ "943": 12081084323522467164,
+ "1412": 13325630770338191793,
+ "1069": 11889908869747176186,
+ "696": 12936726157537291659,
+ "187": 14730723311732531084,
+ "947": 1368799071542715434,
+ "1279": 14164539511590875329,
+ "125": 11247570083424015246,
+ "813": 16843296392567079523,
+ "1313": 4791505715138712300,
+ "207": 15033576355096602726,
+ "1": 4411111828415437877,
+ "365": 5818565957413303678,
+ "562": 10114262463709142275,
+ "286": 15499475567514328403,
+ "1385": 18293827690388125724,
+ "164": 13286340883103593776,
+ "1440": 14730723311732531084,
+ "601": 15720133747284068882,
+ "882": 13267667570180090453,
+ "1305": 4525694840350747775,
+ "223": 10327163164557437428,
+ "1200": 15077801115692881029,
+ "1287": 14964992892658745835,
+ "262": 59522718221868099,
+ "230": 13686135026519030177,
+ "1067": 2553660212441221022,
+ "763": 6942526480989512212,
+ "998": 12802131208636311117,
+ "489": 9159280094613580731,
+ "879": 4668725774621346959,
+ "1417": 8825556416712175968,
+ "465": 7692035629621279871,
+ "350": 14009183003586138017,
+ "804": 10689264369407596782,
+ "741": 17306349474891017794,
+ "1133": 6274766060619645309,
+ "926": 9380746279639997265,
+ "82": 6033144718615056269,
+ "945": 16105221378996740601,
+ "686": 10407745202284682248,
+ "128": 7862337909937037677,
+ "14": 6811678011802554082,
+ "314": 11324830501166740838,
+ "955": 6674679881524428613,
+ "1312": 14837378258056397210,
+ "1162": 8576012958947498601,
+ "70": 9559064180907329581,
+ "1065": 634275039335988279,
+ "738": 14730723311732531084,
+ "906": 2192792045167228140,
+ "423": 10696221757848453707,
+ "1437": 10729362529893780311,
+ "13": 9044454892424012444,
+ "349": 17807677131003544861,
+ "566": 5189199203352158502,
+ "1250": 13751153109297648169,
+ "747": 3692177479886410623,
+ "226": 8964572394001944851,
+ "312": 2734547112070992355,
+ "397": 6118297416388764163,
+ "1301": 17082392871371072744,
+ "1077": 3473277917591090151,
+ "780": 1794973922051147084,
+ "345": 484195107062403248,
+ "1290": 11136380663496036151,
+ "916": 10067064516077251852,
+ "61": 2941092285342913026,
+ "1209": 4995288833919940354,
+ "143": 9176463370625295148,
+ "330": 9545474147295357563,
+ "288": 7888459216179844608,
+ "1273": 4991670405110504373,
+ "73": 6055143889863685124,
+ "336": 11279393024905225209,
+ "1011": 3275088727229879024,
+ "195": 9494279326754918936,
+ "936": 15532378966489563658,
+ "664": 10773996393403493145,
+ "25": 15990441307669158302,
+ "1199": 1135285842178479029,
+ "930": 5556938242854530710,
+ "1233": 6194373938481662983,
+ "872": 16393323238963310826,
+ "69": 13870343466716977828,
+ "287": 12158531988092361931,
+ "1407": 4829186109639124964,
+ "1007": 838045417056660062,
+ "218": 3586441028554264597,
+ "1046": 7048750324672083586,
+ "79": 10677534373939556733,
+ "1340": 7598708748210772725,
+ "1238": 1921500979077291467,
+ "1105": 7970191183024116083,
+ "165": 1166383956648126504,
+ "11": 9079131984217699192,
+ "334": 6300364030797508721,
+ "1042": 13151120281557210458,
+ "634": 15577602415540931605,
+ "1420": 2063165895784197206,
+ "1143": 16938824007929446472,
+ "134": 7783748339965865673,
+ "396": 17565701310825046302,
+ "1076": 4051403372954277094,
+ "497": 1765809466774399918,
+ "122": 63914661033976468,
+ "1085": 5297980694612323595,
+ "1128": 313851090048870239,
+ "548": 9557017284256614479,
+ "432": 12770396287989318017,
+ "367": 13088805233423948891,
+ "1094": 2571155148072116093,
+ "1281": 4592190325523259942,
+ "1082": 580838738530119806,
+ "1144": 17798373570557017445,
+ "186": 14730723311732531084,
+ "1370": 1201946330950737623,
+ "754": 226103985812459110,
+ "37": 15582943496623298390,
+ "266": 7169873957385964446,
+ "978": 3220421929573128496,
+ "690": 10740325592713491767,
+ "151": 14956410332245719956,
+ "1428": 16224413913848920021,
+ "910": 15459495576282681754,
+ "261": 1815365862766042409,
+ "1008": 6357751669116402141,
+ "161": 13866340033929224448,
+ "66": 619532481585618652,
+ "1295": 3789605523338747611,
+ "1397": 14805682373736164579,
+ "85": 6586061114312585739,
+ "255": 16740039171867665681,
+ "1187": 537414383622165332,
+ "83": 5911212488741657956,
+ "1308": 14960515997230526755,
+ "1352": 14730723311732531084,
+ "973": 14730723311732531084,
+ "75": 15983413549368239867,
+ "546": 8291575718562149454,
+ "1439": 9562787989533133322,
+ "939": 9600538487428462376,
+ "487": 9624632344062620462,
+ "234": 15566669815170906317,
+ "1335": 6747225461097717121,
+ "33": 7813362539041301506,
+ "1220": 17866054499646381480,
+ "868": 8398518197062051587,
+ "1372": 11485973008417531564,
+ "495": 2391050953846010676,
+ "765": 14434789190148131741,
+ "141": 6598686754493454464,
+ "618": 7913868822280004097,
+ "222": 2922612539094746911,
+ "1034": 16463040573345134688,
+ "817": 5824674746570294673,
+ "428": 13163943590394193474,
+ "366": 3101995548651046191,
+ "571": 9695454549950668087,
+ "1408": 7427719635506512058,
+ "1168": 13563753100175365146,
+ "592": 15649685632488567125,
+ "375": 2787823416277784736,
+ "605": 18407391443886823980,
+ "371": 1990074650904313350,
+ "470": 5488100901201442172,
+ "660": 7639171232903955610,
+ "117": 14115871436421829843,
+ "1114": 10300590190183040605,
+ "275": 6418334341899795267,
+ "471": 12637011922000873213,
+ "689": 1628553084308372449,
+ "1173": 14092243723278824593,
+ "573": 12515995279447282725,
+ "385": 3018343680007666271,
+ "594": 4361787764832406526,
+ "1342": 395564539347537950,
+ "1425": 8577819891176456578,
+ "201": 3181968108847564977,
+ "842": 7347146027085128148,
+ "963": 1089130612288454599,
+ "422": 16724375930479129846,
+ "772": 15984959106878900952,
+ "1396": 727420435278022919,
+ "602": 15423629626546450998,
+ "394": 312398809057499659,
+ "1014": 8629321927771239274,
+ "1122": 11863940902674302480,
+ "1441": 6149568850139290521,
+ "1090": 12634418673372538856,
+ "1038": 4112876395977609695,
+ "478": 16708530347772175854,
+ "522": 16542782901170924954,
+ "260": 7199508780031064256,
+ "915": 4536356448697058203,
+ "723": 6286968214784565753,
+ "1107": 11177099620922986719,
+ "770": 11297990075341491849,
+ "873": 4930519100666806706,
+ "590": 1509534265197806489,
+ "242": 6500037903951427756,
+ "597": 16283781194094159394,
+ "20": 1393439427780808269,
+ "714": 3090089361341980776,
+ "1106": 6121324536457655408,
+ "833": 12276041377037263827,
+ "866": 4493264567555026751,
+ "968": 6725792277027184839,
+ "6": 12436017974413330362,
+ "282": 2568033251992752517,
+ "643": 12857781747861758970,
+ "1350": 2995529732100092071,
+ "113": 1205699591994545914,
+ "1285": 14431792893025948401,
+ "248": 11908913928477008881,
+ "1403": 17231197606705785159,
+ "1073": 2301331791464016143,
+ "92": 14448725118071871725,
+ "1422": 2494334652330459827,
+ "1265": 19344177603402248,
+ "752": 8254991627016604059,
+ "24": 14991438233778987344,
+ "1306": 16665569153189781908,
+ "721": 1791282459772594266,
+ "390": 6071417381983296135,
+ "1195": 18039860113499928507,
+ "1017": 3896957002842585521,
+ "1189": 2839953548118238080,
+ "902": 12442438713038528075,
+ "196": 5027137721359135771,
+ "1099": 12803248419600830130,
+ "979": 3129990378818482987,
+ "342": 7248364965169523568,
+ "1194": 17257525688679597140,
+ "591": 15338910889590430121,
+ "1121": 12659448173005871309,
+ "1052": 10396040628885576915,
+ "920": 11892750156199070599,
+ "189": 14730723311732531084,
+ "927": 15486209381985567798,
+ "229": 2666072499363042097,
+ "1436": 6403003150805235854,
+ "1137": 10945618090978274553,
+ "712": 3885078350345152469,
+ "542": 16583988953610903629,
+ "893": 14979988292450530382,
+ "1304": 7368158402817943969,
+ "291": 17252571922091955553,
+ "977": 3767418480385636512,
+ "691": 3427587636950436564,
+ "68": 2216542445241535451,
+ "585": 10814092607927011713,
+ "719": 9851945334434065723,
+ "411": 1373794139913835667,
+ "807": 1841460462006039805,
+ "887": 13854431879734880089,
+ "970": 794802052116463689,
+ "1415": 17965414313622763961,
+ "775": 11242240888498331364,
+ "280": 570263452489009017,
+ "339": 7074886701012096472,
+ "816": 4953685977052647658,
+ "821": 16010160041114692209,
+ "595": 3803201488214267191,
+ "644": 11439318688617991563,
+ "506": 3038739295749043288,
+ "1362": 10443936551927841669,
+ "746": 4022910411001710124,
+ "326": 3143380770299098702,
+ "526": 8306150228433334233,
+ "859": 14673244060192137686,
+ "1303": 12250470342707272924,
+ "1349": 10524952658164655083,
+ "960": 991036836219809294,
+ "76": 15112875100280524807,
+ "1299": 2615282628422506678,
+ "1443": 3043241683241944690,
+ "847": 16126853825777568446,
+ "96": 9709934171981028004,
+ "166": 2194534432443092992,
+ "788": 2770068849518024339,
+ "1258": 12874275715711459482,
+ "626": 13699294048522900345,
+ "759": 15329532092126417974,
+ "181": 14730723311732531084,
+ "854": 1147744940585279217,
+ "329": 10569617734608627470,
+ "1268": 349805670285476634,
+ "80": 10011867287391769786,
+ "311": 15937949818505104392,
+ "1035": 1938310322669461384,
+ "787": 4334158480285596818,
+ "127": 6991173428728858982,
+ "1086": 17411505383089981307,
+ "414": 8773159793796196179,
+ "468": 13169198634300052729,
+ "1030": 15293544268784838308,
+ "1333": 6721086470103849028,
+ "193": 14730723311732531084,
+ "316": 1505932298444282239,
+ "1423": 18283977861228267230,
+ "1400": 17334316049467863345,
+ "233": 8082449017714498811,
+ "632": 16951851937506746367,
+ "271": 3706933270131541226,
+ "364": 1750512054828357585,
+ "855": 16397598946780028384,
+ "205": 3080126214403770943,
+ "490": 8433010507129995929,
+ "1261": 2339399156931116110,
+ "1084": 15188362099238085613,
+ "1207": 12972784638187358411,
+ "1393": 16721477676868155143,
+ "35": 5252630756371805841,
+ "1158": 17233318466710135019,
+ "1315": 6561134269660418125,
+ "897": 13642350485249624505,
+ "647": 6385592409438736115,
+ "1323": 18061295190052776192,
+ "524": 13531846297743576490,
+ "1267": 14594056972474652711,
+ "382": 15234355429173217207,
+ "861": 16732534253989976653,
+ "1264": 9203080129194527562,
+ "1012": 5642915419735004995,
+ "886": 1634709068781049257,
+ "369": 3992896044124716988,
+ "1348": 2334560116364774862,
+ "435": 4089345145252163811,
+ "114": 169081054370345097,
+ "1280": 17544768750178347189,
+ "1062": 7151435211445546005,
+ "112": 4567499042450877698,
+ "1346": 16615318469613980654,
+ "530": 3259007875266537660,
+ "965": 5859484896757779783,
+ "684": 12548313238697570007,
+ "727": 11477570892773934270,
+ "1037": 3962083214435925087,
+ "680": 14676336483071137987,
+ "742": 11943854537314156948,
+ "703": 5930657449313146400,
+ "534": 3658382012654874477,
+ "319": 6473493951362391965,
+ "1138": 4335786842319401988,
+ "1274": 2218833986995406845,
+ "241": 14134486126650145569,
+ "116": 913503402705544511,
+ "372": 4229913151152491569,
+ "825": 2763964565145473702,
+ "700": 2563878526204381667,
+ "1180": 4510172881497053099,
+ "525": 2197450609900186441,
+ "1031": 10881005068483689715,
+ "41": 13473779141418478792,
+ "192": 14730723311732531084,
+ "467": 15456785442186642101,
+ "150": 17717822323378294856,
+ "676": 4437834985213879972,
+ "472": 11300405685528200593,
+ "856": 12736437803935191391,
+ "671": 6741205036754008861,
+ "1418": 8214451289346248901,
+ "596": 6707418962307332397,
+ "570": 2584575629245746470,
+ "302": 5733812933378100242,
+ "766": 3965981169480641753,
+ "123": 13949979204641131669,
+ "556": 3138402742752041092,
+ "736": 7479748036002459111,
+ "62": 5371403391438870935,
+ "1146": 7924780405413932304,
+ "857": 8427180993390397422,
+ "750": 2653516471766836183,
+ "593": 8721102569140709126,
+ "1032": 1169569965714340267,
+ "104": 9080293517774209772,
+ "993": 1108423164682098749,
+ "170": 4811334172677969891,
+ "778": 4594759610091914754,
+ "547": 11076133666026579657,
+ "1358": 8935272494190254627,
+ "624": 17791629164475377300,
+ "446": 1817100882001592032,
+ "1088": 16087645126711144167,
+ "1341": 1719571165994773448,
+ "1283": 6949158664632035433,
+ "829": 7026837260660620674,
+ "494": 16257600679717423766,
+ "252": 9553380881582636792,
+ "1009": 11857329139258629993,
+ "1309": 9054675059131291730,
+ "351": 16936423743959268928,
+ "1244": 11409399189484604958,
+ "1351": 12254064252247280699,
+ "337": 12073930616145665366,
+ "1036": 18329820675295486070,
+ "1378": 6273075298741554904,
+ "1178": 5695292664962965529,
+ "654": 1339968309181099300,
+ "990": 1842443744707303142,
+ "4": 18389722049075012359,
+ "1310": 4549197480540752049,
+ "1196": 8859912096389990386,
+ "1431": 11823062883352541772,
+ "682": 5076684826076883864,
+ "550": 17751106568716137387,
+ "477": 14235806955538184766,
+ "611": 16107123120705328157,
+ "1222": 16857043670368315711,
+ "307": 15200302302531916622,
+ "157": 753757631627412361,
+ "1275": 2297935350042233194,
+ "586": 12395498569698034018,
+ "1311": 15247903928747862526,
+ "1153": 17972396611269365768,
+ "459": 14801893088957028131,
+ "183": 14730723311732531084,
+ "709": 7209570295138474166,
+ "158": 4361333235019622034,
+ "199": 10349679144714916206,
+ "812": 14142012000553479339,
+ "346": 8942484529050543685,
+ "539": 7429277144499656989,
+ "294": 14866540542576808700,
+ "56": 1211267824793930890,
+ "1356": 13066377133648539587,
+ "826": 14789154462476826622,
+ "1022": 1244310919017186858,
+ "1307": 6195955464493337835,
+ "509": 2274295408840801419,
+ "884": 8385021273835621172,
+ "224": 11295279579847973207,
+ "399": 908063184894831296,
+ "802": 6214585924037640057,
+ "874": 1878965558588822062,
+ "891": 16835604768171279148,
+ "1079": 16031879532100463025,
+ "393": 17312987599284430283,
+ "954": 17467275265956784141,
+ "706": 17505654807005893914,
+ "1029": 16727767372613328859,
+ "1198": 17381818866151411651,
+ "174": 14730723311732531084,
+ "44": 10032124995374981970,
+ "1203": 5133258749058162369,
+ "16": 13566982580242337315,
+ "851": 7531005787966329977,
+ "834": 12958638709869365612,
+ "957": 9218344534211332094,
+ "791": 4571312353353034287,
+ "405": 2792241983237138177,
+ "572": 6569151369443102371,
+ "403": 3917539378235224523,
+ "45": 3881544267432275150,
+ "1157": 15865589582360561274,
+ "1186": 14664349775972519372,
+ "1123": 897612757393133909,
+ "320": 4703250786899893861,
+ "553": 5836266551884328111,
+ "606": 14737987360877119122,
+ "237": 7203327499112826098,
+ "1374": 14415873778522872280,
+ "315": 10193550219355427921,
+ "417": 154483065168881252,
+ "457": 15813307459416878678,
+ "799": 14730723311732531084,
+ "464": 2669029203296951281,
+ "1166": 16481870663678621619,
+ "1070": 16199471318887141628,
+ "31": 5750044737889454320,
+ "1405": 9257828251841422912,
+ "138": 1433327735557702867,
+ "301": 6579114151471392624,
+ "790": 1711286836351388652,
+ "704": 2085729468091755846,
+ "126": 5893496003753616820,
+ "1152": 13553356174755053850,
+ "391": 14376844443269982927,
+ "1386": 17306381253778944212,
+ "1134": 9309758412964883966,
+ "278": 2021710066823780300,
+ "1319": 10200663886350685572,
+ "171": 8573822643429771749,
+ "786": 7556976949434320938,
+ "675": 17682299233371738561,
+ "1322": 3846084421686594166,
+ "277": 12033803529868763143,
+ "1127": 11374493998941412267,
+ "1156": 18294018540981987190,
+ "84": 8904210948883198013,
+ "795": 15185972954479308303,
+ "536": 17327199690633229726,
+ "732": 13623545315437265953,
+ "728": 4229865866662965612,
+ "969": 6509484567299762789,
+ "182": 14730723311732531084,
+ "1317": 2443203333418795785,
+ "74": 8301823809323395858,
+ "475": 13746216514152130361,
+ "1218": 15802766342917981563,
+ "1329": 10803866802886183035,
+ "327": 9235899167961520139,
+ "1434": 2046479435749142196,
+ "1292": 16392822552084263994,
+ "815": 15473145533050550473,
+ "148": 17639785026763830474,
+ "1188": 15948903207114212731,
+ "436": 5898867406907405362,
+ "1078": 10393164116552752118,
+ "988": 1871918553676021598,
+ "1170": 3154002251872734459,
+ "406": 18304630704626910684,
+ "1211": 13664912818051425526,
+ "21": 13593975029386737532,
+ "1072": 11303013454397276654,
+ "1451": 3221146872881338007,
+ "779": 8446925898800986328,
+ "317": 8916850115257823927,
+ "1039": 16885444854060321820,
+ "240": 9677520503653634631,
+ "1048": 4477230427358395115,
+ "409": 10427823664434422942,
+ "645": 1827040298377428454,
+ "810": 11027496107183772129,
+ "129": 15663038308788880456,
+ "843": 3536297931803133152,
+ "1025": 12516964012283431605,
+ "1159": 3138205084962945695,
+ "877": 12003234613401180358,
+ "97": 4470616987160186036,
+ "781": 1957769147213616694,
+ "507": 17466129514864102405,
+ "442": 10975648869328498744,
+ "1055": 17414717121005679885,
+ "933": 10106022965277886754,
+ "109": 10967111230014338229,
+ "889": 5660010160179588859,
+ "418": 7084732236109162498,
+ "267": 579538539716627329,
+ "1404": 13320880559277496394,
+ "352": 7362093208338317268,
+ "941": 5371799808832846202,
+ "783": 18188032968418418144,
+ "828": 14269195431791604997,
+ "424": 10959619926040682621,
+ "209": 14965471386931825577,
+ "368": 11472180730902231020,
+ "348": 8818925372647231957,
+ "751": 2057633144327586415,
+ "935": 3978534758478187742,
+ "1327": 17623179190290784374,
+ "1424": 6374221440988334258,
+ "580": 10987409064275677937,
+ "413": 7278564940307624099,
+ "870": 10644998033659879566,
+ "1344": 13378824652873193763,
+ "568": 12754955068677577455,
+ "865": 9413015906249620842,
+ "65": 7125777954604257397,
+ "600": 4632451917051323394,
+ "67": 17305249497312487385,
+ "491": 9446245326290985855,
+ "322": 11805526639707541334,
+ "1343": 16275225668405863922,
+ "666": 8374218111674883162,
+ "1142": 12053947532551371686,
+ "710": 10523531369179662392,
+ "642": 13918252100313379360,
+ "1330": 12385404711119560524,
+ "705": 1673513815614233412,
+ "1266": 18313388546235941158,
+ "297": 14608357369080764257,
+ "1095": 12489160366972218131,
+ "761": 9303592790438333818,
+ "499": 10620988923885320256,
+ "694": 15593777358157338127,
+ "681": 12979391150020218778,
+ "1444": 10085045911936522933,
+ "901": 8449957792989376496,
+ "986": 9406358096607325353,
+ "27": 11840473557301995397,
+ "535": 13763380669456291707,
+ "768": 17599520152973760330,
+ "272": 11963870078753273076,
+ "1300": 450561145214938830,
+ "523": 6962694580686018310,
+ "951": 16833324419690310355,
+ "1164": 13148051261295522895,
+ "794": 5292607899440973618,
+ "678": 6890509782423370951,
+ "425": 14584016982842469143,
+ "720": 5160190613109316624,
+ "934": 15024051433925468145,
+ "862": 9273738292725839841,
+ "845": 4064470756377538558,
+ "1406": 16410963488829723493,
+ "797": 16077525533111494091,
+ "1254": 17480331179516984321,
+ "864": 52590887468997661,
+ "1282": 5919972529020435166,
+ "1019": 15454669445626310212,
+ "1355": 8741801159039608899,
+ "474": 13608285581489418136,
+ "175": 14730723311732531084,
+ "59": 16348495970077493916,
+ "756": 7653495239604695859,
+ "492": 8231751668655852124,
+ "147": 9187193474659502763,
+ "511": 17852429440943427218,
+ "502": 380085126544419876,
+ "376": 16610598633516514853,
+ "773": 1032353189143690953,
+ "646": 7770348631408804998,
+ "641": 7859145546022903897,
+ "202": 6508929137345512716,
+ "296": 13927502033178440142,
+ "903": 10733628149178919196,
+ "407": 15383673201052214176,
+ "496": 9946297767831796596,
+ "1391": 14730723311732531084,
+ "875": 17054798686008329403,
+ "1197": 1413621127458542938,
+ "520": 7479219695149995436,
+ "917": 15826432253549659901,
+ "191": 14730723311732531084,
+ "777": 6940976848723687478,
+ "975": 11591231186311099559,
+ "1249": 850597848207700319,
+ "589": 2808187964647177078,
+ "516": 3966697575903472018,
+ "1113": 6836506003593506607,
+ "359": 13480715980257768916,
+ "500": 984646497619939873,
+ "149": 12021163335447072859,
+ "238": 13344885717958042947,
+ "1044": 13343595583414225902,
+ "232": 294251838825478301,
+ "576": 1891154990367049482,
+ "486": 11858693435097165892,
+ "292": 13931219932277474773,
+ "504": 9361005207910442374,
+ "574": 15575655529915110051,
+ "1247": 11638426755165289323,
+ "698": 14344609463009343703,
+ "338": 13898394328531951538,
+ "753": 13701403964131916144,
+ "387": 14292873258269133085,
+ "1190": 8796023144815975935,
+ "89": 1740903075828759384,
+ "1399": 17538893418979057590,
+ "985": 18053029763468723557,
+ "1101": 2637681801721498881,
+ "685": 9898258425195512289,
+ "1232": 9202562893012668968,
+ "649": 8631517693974656789,
+ "708": 3141491677155789233,
+ "663": 1711608129712097561,
+ "878": 11223390385243529892,
+ "395": 4957355313160305340,
+ "244": 18306744070439263154,
+ "1176": 16605209617789700622,
+ "1256": 2143021529483886432,
+ "1302": 13589648792115922507,
+ "713": 12839583763345761122,
+ "227": 1317667912842129384,
+ "1124": 16681609451947624160,
+ "892": 3100909089860026642,
+ "1390": 208535008110244385,
+ "659": 3263125467617187159,
+ "1314": 6423506785454020056,
+ "443": 3334504424206070813,
+ "1379": 7717529923894161970,
+ "225": 15263258829493000404,
+ "410": 10624931313382192128,
+ "1110": 1097346600936035463,
+ "840": 5650914648416542432,
+ "852": 8840322347931883019,
+ "501": 7356884989155150976,
+ "798": 2347505988350421533,
+ "925": 13198674479166639486,
+ "7": 13154886192948926309,
+ "1359": 7769808361719619617,
+ "1429": 16399288739000522471,
+ "308": 7422099937373504796,
+ "695": 4200128086236953833,
+ "163": 1635902368505350341,
+ "1013": 9076639691750811893,
+ "132": 2041063769162863544,
+ "347": 16926639273403250238,
+ "1270": 17974227208504508258,
+ "383": 8856424797733027979,
+ "769": 2977276566906795264,
+ "832": 6638508751971240504,
+ "557": 740259504325838333,
+ "809": 14650801453219633436,
+ "458": 2251165614077146213,
+ "1130": 8203200783487455392,
+ "621": 6701921678883373607,
+ "309": 15058479806928874549,
+ "1010": 531089159936877217,
+ "28": 10926717158207293178,
+ "142": 8815261221801146559,
+ "81": 1305563985371279733,
+ "737": 15565817855535417144,
+ "1409": 17011676078105466356,
+ "1298": 14553703913152698652,
+ "731": 15326788457627837174,
+ "1111": 5996109224670986837,
+ "729": 13707375401072871736,
+ "1365": 4101224559310103150,
+ "715": 15316515820442629591,
+ "745": 6385135569170506512,
+ "1251": 10041798354849178514,
+ "216": 16785293096841313385,
+ "1228": 9662076760355508668,
+ "1092": 13187158525560771654,
+ "537": 16629858519435758338,
+ "2": 5535478552780071382,
+ "86": 4232804557527702433,
+ "259": 12178302224067644275,
+ "615": 683783138435330738,
+ "931": 9551766273928950851,
+ "824": 8668666962103482425,
+ "136": 5354006083123928149,
+ "1442": 4310331481500278682,
+ "1321": 15164401704328708632,
+ "64": 17562787630582831176,
+ "1276": 16736756350909153631,
+ "996": 10064756513512919648,
+ "1384": 6850488854918996962,
+ "256": 18254254365941722947,
+ "431": 13110519820235013787,
+ "579": 4276304285123439505,
+ "1411": 7833841941360791990,
+ "482": 18076319120555106829,
+ "1316": 15110544130141264037,
+ "51": 13092233040804466404,
+ "190": 14730723311732531084,
+ "328": 16766834114648635953,
+ "172": 14753238098210611700,
+ "1271": 3627726130927478213,
+ "577": 7352714042660608899,
+ "52": 13748295770059669596,
+ "657": 1960026119159509102,
+ "629": 4917645448230090382,
+ "1394": 18057794730767120378,
+ "358": 14049234180703608394,
+ "1471": 723864063496621644,
+ "789": 7705221806723981176,
+ "1182": 6884840675329360531,
+ "628": 15077416703178709831,
+ "440": 7111405702273017869,
+ "55": 18430150783270530113,
+ "331": 15803421854236861087,
+ "1160": 1417509085856386832,
+ "575": 8472868209216510366,
+ "863": 15686441396117048216,
+ "426": 3422286874011386603,
+ "1375": 8858682370908880636,
+ "674": 10781471317130440610,
+ "1074": 10585611459347626535,
+ "848": 8607683853624522112,
+ "1214": 4869675435950376097,
+ "270": 11646649312045820205,
+ "505": 4283048002040754050,
+ "528": 13055525675677838192,
+ "1377": 12944168734052709271,
+ "246": 5487869323207277063,
+ "1260": 17748395682391074844,
+ "404": 16163901688947461679,
+ "462": 18392326091886105165,
+ "135": 17411335444726690382,
+ "289": 5176833794678224843,
+ "178": 14730723311732531084,
+ "911": 11780269433330192103,
+ "921": 3584741847288511663,
+ "560": 8379703195638223559,
+ "1357": 1239932432142619082,
+ "484": 7693201794386153671,
+ "692": 9323445648394426031,
+ "124": 4351858018885716235,
+ "1064": 4256288555307304634,
+ "1297": 1967903820707650824,
+ "531": 7165684393731254531,
+ "718": 1222882218478120209,
+ "1119": 13941337819272574643,
+ "99": 2784769328788677890,
+ "635": 5334621617493824670,
+ "512": 9617528792682713225,
+ "91": 12382402938583363420,
+ "1139": 776530932894948553,
+ "1229": 10406119633558090066,
+ "49": 11596425998354410460,
+ "545": 15893448783726562788,
+ "1083": 657675715687338355,
+ "1325": 12964558679546553820,
+ "610": 5804117245681639505,
+ "1294": 12656968362177190338,
+ "952": 675191243880042865,
+ "932": 5858445811142641004,
+ "94": 17005552713235578730,
+ "1129": 16230109820893887525,
+ "159": 18350076748695301874,
+ "373": 11123986548443038474,
+ "269": 3027228227305573481,
+ "1426": 1019540039154555301,
+ "453": 17689701627487880961,
+ "184": 14730723311732531084,
+ "616": 17811221691625063330,
+ "1118": 8849050131548953112,
+ "357": 14450432709998106572,
+ "102": 17543177387646670241,
+ "836": 16350053574948432822,
+ "455": 4004429531063776081,
+ "26": 12924816684556971175,
+ "699": 5405817668925536847,
+ "1098": 16253311617423671116,
+ "1060": 1352048425422223734,
+ "434": 18345441805467601300,
+ "748": 17833170840426464783,
+ "412": 782594845789499091,
+ "318": 17128387513728158085,
+ "844": 8731552282868355275,
+ "1398": 7379468193563733240,
+ "438": 11421103587123991086,
+ "912": 5789137293034537384,
+ "940": 533009281035445678,
+ "1177": 7079070955853380225,
+ "306": 18349464699394576243,
+ "1193": 8503633101519409321,
+ "485": 9490230996848537412,
+ "835": 9725230710451544621,
+ "564": 3681490231653370236,
+ "324": 9370467645347790658,
+ "1126": 16528321051971645922,
+ "662": 2350871931168380611,
+ "617": 3287913796494498212,
+ "1183": 9190884173356780157,
+ "717": 17856580044161032130,
+ "156": 11479530001660668496,
+ "822": 12844452505074946288,
+ "604": 2134447317374110699,
+ "1116": 16274459724567257937,
+ "1246": 9118665318286953272,
+ "1402": 2472736580355535502,
+ "10": 5259884897011777854,
+ "185": 14730723311732531084,
+ "1213": 6532157983720321605,
+ "253": 4785348470118249730,
+ "541": 15393006485772981899,
+ "211": 2578790908847958136,
+ "549": 714800787264924700,
+ "1147": 11893748933626441402,
+ "265": 2206885897000798431,
+ "429": 17395300726111262288,
+ "155": 7576579451786727689,
+ "981": 4851805379396060481,
+ "623": 15204256170951310252,
+ "228": 6550732449686752455,
+ "1131": 14746711646637885894,
+ "111": 12546797527417305503,
+ "488": 10726134634307066335,
+ "119": 3051423683430548308,
+ "1206": 128442903845811340,
+ "1169": 10900424675098966372,
+ "1338": 11591026292838365249,
+ "1023": 16180622165481049083,
+ "565": 1252223822259064460,
+ "1201": 8941943143682508269,
+ "724": 1765111574982592753,
+ "722": 7154981378637694301,
+ "1026": 13750721984593011904,
+ "108": 1480221456981282431,
+ "1432": 850881253503445310,
+ "217": 6187636265436074131,
+ "867": 16462599544051988179,
+ "1361": 6257419634535132317,
+ "177": 3811940342133613354,
+ "1245": 9295425109981871549,
+ "439": 525257876079590040,
+ "896": 8307671875626640027,
+ "305": 18002093376616455581,
+ "1353": 6152941047127893424,
+ "1293": 9823885296484836662,
+ "739": 3456076992387622282,
+ "304": 6039100348039510554,
+ "1053": 2643656835971183809,
+ "608": 8174132626930998310,
+ "555": 17578296354718995355,
+ "668": 9903640117893670069,
+ "538": 7445395709563801550,
+ "513": 12134930973353414110,
+ "989": 613458148406460277,
+ "652": 2625420597035822753,
+ "1231": 4513923592153521912,
+ "995": 1269028070449274524,
+ "50": 16990469689004420450,
+ "469": 6358089202080305869,
+ "598": 8187562266504014009,
+ "243": 16718814063318985777,
+ "221": 15562451532811780538,
+ "447": 13871678257176729705,
+ "764": 4487334387084545251,
+ "1242": 17313582343868914503,
+ "139": 7424526249356584655,
+ "1059": 9614610658346065308,
+ "160": 15857642203024843223,
+ "584": 6856740761085726222,
+ "93": 2273484794413135669,
+ "105": 17609609534801664643,
+ "1061": 2943006878967558456,
+ "1259": 12945624254066605155,
+ "1367": 4056475417351336903,
+ "213": 15507906451260121345,
+ "518": 17045921833994891974,
+ "1208": 3983322860953247338,
+ "1324": 12261410600123234926,
+ "725": 3536579528039047360,
+ "1174": 16472578128650267865,
+ "333": 11121457472884096843,
+ "515": 16289337177879854889,
+ "274": 4667621852904824916,
+ "258": 13242990336919292764,
+ "3": 11464742812273593900,
+ "508": 7757989646317226294,
+ "343": 2864808277441033180,
+ "437": 10265042281458294317,
+ "653": 14252840806035507844,
+ "734": 10669840528326140896,
+ "651": 6180797274160387263,
+ "1091": 12661420219799538925,
+ "1001": 9547528035451769032,
+ "386": 4112658703532443027,
+ "57": 13310239519894386517,
+ "1332": 12575112886760412897,
+ "379": 2563072330255086975,
+ "976": 8704191222663366346,
+ "257": 439864741893032447,
+ "1380": 16083567560347890601,
+ "1239": 2163044105208266807,
+ "1286": 9697026925453712853,
+ "1354": 1082374989774341332,
+ "1150": 18149936966808972642,
+ "146": 416473696236015813,
+ "697": 6518095054476166845,
+ "905": 7858899486831136267,
+ "236": 15995231379547312008,
+ "1002": 16184542731035761811,
+ "625": 12789687517867825657,
+ "683": 16717881483333325267,
+ "924": 8583007603338427290,
+ "254": 2853270682999868072,
+ "88": 17198521142048972615,
+ "1192": 12991553558564341699,
+ "983": 9299029978572826757,
+ "454": 9665110631743714031,
+ "1135": 10627256093645006359,
+ "890": 17048285429538009021,
+ "949": 1630228795272646057,
+ "1381": 11962583175642208414,
+ "1024": 15264422872062000164,
+ "235": 17321286559855180275,
+ "448": 5113521272795230453,
+ "90": 14402152349367228985,
+ "631": 5585603003587616015,
+ "563": 14346601543926116583,
+ "938": 17114256041041850723,
+ "655": 2610130387608313171,
+ "276": 5140613859145147614,
+ "612": 5756765916823595798,
+ "1255": 14048697402545569872,
+ "774": 131387921515373335,
+ "449": 15385528054650457871,
+ "784": 17864874745797477207,
+ "355": 16319493035693486399,
+ "284": 6565705192871688060,
+ "1179": 8858145491079901716,
+ "716": 5222493530258227383,
+ "1289": 15914411244207708450,
+ "1364": 12915601559971616871,
+ "481": 7769995221215262065,
+ "176": 14730723311732531084,
+ "994": 12190551145431051778,
+ "398": 9117627809278315833,
+ "1277": 1226421828309957556,
+ "1089": 14447637372971581482,
+ "1382": 11949553246616031488,
+ "762": 3102124445745655,
+ "1226": 815768833748431031,
+ "846": 7561025089136052891,
+ "415": 6692164510166672762,
+ "569": 15817868289971548142,
+ "837": 17696528458205689687,
+ "354": 16450287701453273910,
+ "476": 15174366567019374381,
+ "1328": 17305855479589203749,
+ "77": 817074884735616284,
+ "999": 3139083619993320315,
+ "341": 244656397663576618,
+ "1109": 14317048769711611045,
+ "1136": 11128980657959595199,
+ "1151": 2351561260548090068,
+ "400": 10773722413590522463,
+ "869": 14201228969363652344,
+ "1326": 12946356223947764398,
+ "937": 14637429435672626531,
+ "1401": 592099939886852772,
+ "1366": 12351429695204357678,
+ "1369": 14904507310972872784,
+ "381": 4679913599888417006,
+ "514": 9151799679175801729,
+ "210": 9381310075730490912,
+ "179": 14730723311732531084,
+ "1140": 13026641430015972012,
+ "749": 15872604204113427664,
+ "1020": 14655959376728981653,
+ "701": 13703954308305314449,
+ "1387": 9990780042025651203,
+ "313": 2220643170100433637,
+ "1217": 3001277235809054880,
+ "904": 7062989530396318349,
+ "194": 14730723311732531084,
+ "688": 9566840876936574676,
+ "300": 15130938388835441748,
+ "521": 848447394906044273,
+ "101": 6359234622686630145,
+ "687": 8980414948133543687,
+ "479": 3323630342694851355,
+ "1284": 6452305689672172260,
+ "1167": 8446230359172150897,
+ "630": 17512690281001718809,
+ "860": 5058319522823661598,
+ "1120": 7259159406059294531,
+ "1004": 5126295064268363174,
+ "433": 6941902345281508400,
+ "1115": 5053419920300470436,
+ "1021": 16884587174128313836,
+ "1470": 117048625990545678,
+ "208": 5222894002828208982,
+ "730": 6074807823691208828,
+ "220": 16504798159313504899,
+ "997": 6411499951929855729,
+ "961": 7767430480900480757,
+ "776": 11561124119648912867,
+ "956": 11306613301745295635,
+ "131": 3642912428502406860,
+ "36": 12152370987546121612,
+ "792": 10929214164730263336,
+ "962": 16715748373380084038,
+ "758": 15364596721207716183,
+ "1093": 7141723654754540908,
+ "1373": 1471738410240488487,
+ "1132": 897354770180680204,
+ "1043": 2356709451114839192,
+ "1027": 15727630602333802040,
+ "1383": 7530460071049038142,
+ "619": 7178511271721856193,
+ "1230": 228468728218289920,
+ "188": 14730723311732531084,
+ "363": 3229028746147891441,
+ "430": 14407521698908397673,
+ "360": 7918848167651858694,
+ "299": 7629257068651253201,
+ "1205": 9030669390298460972,
+ "1191": 9084263848696760595,
+ "1054": 12939190481738587844,
+ "1097": 4782465023082846664,
+ "1360": 14504809371036611815,
+ "771": 1695363826065342603,
+ "1185": 17463914098138008938,
+ "1103": 8535000797119514265,
+ "1171": 7303858770870479984,
+ "1221": 2197754949082347923,
+ "145": 9534848515840063164,
+ "1100": 13875786444738296559,
+ "1427": 829882149928361110,
+ "909": 16075069926292804088,
+ "1051": 1851170011431584279,
+ "239": 9679274664718995230,
+ "636": 3850976217989617879,
+ "1252": 10362489494479997455,
+ "806": 250081830937560032,
+ "733": 15928258759114320061,
+ "206": 15170923825406858600,
+ "380": 8132145700976121576,
+ "362": 3423892620648639210,
+ "285": 5045961731648881968,
+ "899": 2439619009731451271,
+ "1210": 3672756240617208478,
+ "1163": 1873538642809728762,
+ "578": 2927482822016453753,
+ "1212": 5292609427532706923,
+ "370": 9725046504813367435,
+ "5": 7772237163619658650,
+ "559": 15451489340080068019,
+ "1473": 11257165554784037421,
+ "19": 11066569371437555348,
+ "1296": 6166160568896094280,
+ "1204": 11748888661373174306,
+ "895": 11021449375595520122,
+ "1234": 16202742038168425350,
+ "519": 2114974001749420449,
+ "849": 1116936465421786469,
+ "1257": 11293871655915780909,
+ "264": 4390948712072026372,
+ "880": 5510871216094095995,
+ "295": 11883897371156326438,
+ "152": 14813254921827981304,
+ "290": 11964962635408711840,
+ "992": 15301592437588933424,
+ "950": 10502219346766571112,
+ "1389": 13608702698184560470,
+ "707": 13440752346153956858,
+ "356": 14422262581351587469,
+ "1087": 17389789319228379889,
+ "283": 15230504941339297949,
+ "180": 14730723311732531084,
+ "735": 7881517462421262513,
+ "1345": 6672946304479325594,
+ "8": 9984652467301630045,
+ "1368": 3246746503583665106,
+ "1057": 14977865803706432251,
+ "1435": 12687057810892357735,
+ "1028": 1861857733081519647,
+ "669": 1754763392608219584,
+ "140": 3985245279542478184,
+ "1047": 5790165366744088314,
+ "173": 8914764404835824609,
+ "850": 3201288978125697890,
+ "1272": 3658259606752603115,
+ "1395": 16685533456403164286,
+ "805": 14950203214362016168,
+ "353": 17906260841060084377,
+ "944": 7953303632136339461,
+ "1155": 7158966121200595074,
+ "1006": 7318153699001771796,
+ "1015": 8030978265733454321,
+ "620": 7044610218387743682,
+ "43": 669700676801263900,
+ "622": 5588517936278638055,
+ "9": 35292805982035287,
+ "918": 15376232548596537259,
+ "914": 4250303357942902575,
+ "198": 14526588073800965483,
+ "63": 14412953618821425159,
+ "1336": 3760960022759859119,
+ "335": 17762501371630263048,
+ "554": 17048818236163250220,
+ "48": 17313027418537344151,
+ "1215": 15076236550887974427,
+ "245": 6282767538085775226,
+ "552": 1009732962893169244,
+ "609": 10398340886863329894,
+ "420": 2558607973992816125,
+ "1450": 11628893429634094310,
+ "561": 7579190768337951036,
+ "303": 16902660848918464492,
+ "1388": 12428076504963981325,
+ "1081": 11473437365183300891,
+ "169": 2612695663806923638,
+ "972": 14730723311732531084,
+ "650": 14068345465382713069,
+ "15": 3764260319710850285,
+ "928": 4095883881993213565,
+ "483": 18256620129577596052,
+ "693": 15755301229159718202,
+ "527": 7164607314149109667,
+ "451": 12825238574126460966,
+ "811": 11647395756895884463,
+ "1421": 5746358907829749111,
+ "121": 8557783343947419521,
+ "803": 9691631072733232612,
+ "103": 12437698100761503082,
+ "1263": 5006585042798108421,
+ "480": 4999804578752048420,
+ "133": 3428134945143145240,
+ "648": 5883616878189020561,
+ "167": 15313859743592177196,
+ "1148": 9762285047639930417,
+ "377": 8963339232815194833,
+ "744": 4769506887765277404,
+ "144": 14248193350087043544,
+ "214": 13713181715569127301,
+ "130": 4846026544855535454,
+ "588": 15956432408381858970,
+ "982": 5006903806801976007,
+ "1339": 9051348180748607483,
+ "34": 6084612562396891411,
+ "567": 11796687169670755050,
+ "197": 10256186000802007873,
+ "215": 3244197898343821688,
+ "87": 8599364223638627144,
+ "408": 17959844961130524584,
+ "814": 3739740706010533174,
+ "987": 17308929008462392289,
+ "452": 10935575084113291450,
+ "321": 1318917782747579161,
+ "361": 18269932950992783377,
+ "419": 8598504382806398504,
+ "544": 11791297547466411795,
+ "38": 7110219231479427462,
+ "1000": 4414333643299374504,
+ "203": 8834524541898200428,
+ "1331": 13731260537096014282,
+ "740": 13074337569197134944,
+ "607": 11772366051510573440,
+ "1071": 17051036124897252963,
+ "466": 4166999380157799737,
+ "1291": 2874071486339649911,
+ "830": 5092574366791821665,
+ "344": 5517046146168487781,
+ "885": 8606872099569743500,
+ "679": 629709277020917131,
+ "388": 16796749139709897473,
+ "818": 6962225281161448616,
+ "913": 11063354789701561779,
+ "378": 5431585071817923875,
+ "898": 11361017648950178907,
+ "633": 14238327620704487293,
+ "107": 3994167527996453282,
+ "1108": 17702500033183447334,
+ "374": 1939717168004893685,
+ "533": 8568140098161010163,
+ "1104": 13481007953839684340,
+ "18": 13958788744760151587,
+ "450": 18002447546625842523,
+ "251": 4713812010736147352,
+ "1063": 6424128622179003475,
+ "95": 11354925438287538532,
+ "247": 2843055036004736452,
+ "1141": 18035559375488954705,
+ "532": 15432058324982451005,
+ "638": 10372103509167421364,
+ "219": 7636148767448647844,
+ "310": 8081199917463525153,
+ "702": 8910885520621724447,
+ "1202": 17291544996960787118,
+ "599": 783804872848852374,
+ "78": 5059062080871831735,
+ "922": 2896385206643785314,
+ "1337": 13841287187630694874,
+ "1278": 2459843613268470128,
+ "200": 6405813549689670588,
+ "389": 14427284512084841161,
+ "54": 16450687772847513412,
+ "1371": 5585804284456174272,
+ "98": 2384911217532985357,
+ "760": 7391971930867512433,
+ "1410": 469765144492162369,
+ "427": 14517595672597046024,
+ "1003": 2616323609256598054,
+ "1334": 12125853783646006629,
+ "1050": 3976870525067930926,
+ "614": 6063800038969795482,
+ "1080": 3234088282083345176,
+ "441": 16136090603553508464,
+ "162": 13502663073024860635,
+ "332": 11810290220243264973,
+ "1227": 15572520852196226759,
+ "1237": 11041607324859766685,
+ "543": 267750943456857237,
+ "53": 7429608235762060661,
+ "841": 12962917907070185039,
+ "640": 8031376622194784674,
+ "900": 7900756029095965430,
+ "1016": 8813202133066274814,
+ "639": 3141217035593944230,
+ "71": 3091564728653960549,
+ "823": 7212629308185619983,
+ "558": 18440003100508973042,
+ "819": 11693440790374699594,
+ "800": 14730723311732531084,
+ "1419": 7316561368548889489,
+ "1240": 3626574373044012987,
+ "1068": 12753058222902094298,
+ "106": 17101136076381858494,
+ "384": 7004424625111143297,
+ "1040": 2728666551978686672,
+ "281": 7218530809505198431,
+ "726": 11882083790956293692,
+ "1018": 11014435187782529327,
+ "46": 255437359418964684,
+ "1430": 18164842412435697126,
+ "293": 17160003553693887619,
+ "1243": 12061759456712365231,
+ "948": 1399226538036217420,
+ "340": 15512243413780820807,
+ "416": 18262544314450655765,
+ "1165": 6179148276853256711,
+ "1117": 11561472039497326915,
+ "231": 11813343633873696226,
+ "1058": 1697546234005183745,
+ "154": 7854500753484278204,
+ "473": 4599019113002726373,
+ "529": 8701602760537460250,
+ "58": 17505087297226394106,
+ "1392": 14730723311732531084,
+ "583": 11710068429072241481,
+ "1125": 3710590138790045328,
+ "137": 2379042457734778297,
+ "711": 13016460131359053139,
+ "323": 18443012440502191918,
+ "1433": 12385412693830174286,
+ "831": 10608641139940405363,
+ "1223": 11927017222584639849,
+ "47": 7140847712545980299,
+ "838": 5976513984079201821,
+ "971": 14730723311732531084,
+ "946": 1537726874950466345,
+ "12": 7646446858500474621,
+ "907": 15780607099591949841,
+ "401": 7193207907539957544,
+ "1241": 15646936344053160627,
+ "1145": 3057618859283047653,
+ "498": 7697158640754547893,
+ "613": 7015915920044844487,
+ "1269": 4845574085552400075,
+ "984": 14328450817703348315,
+ "672": 9664397287304630018,
+ "1096": 10465270929561638853,
+ "402": 9692012912002679888,
+ "263": 14352936684372788149,
+ "793": 18388426045295079917,
+ "17": 17897516341273000378,
+ "421": 12459994441690431211,
+ "665": 6617055692001697233,
+ "60": 4460957908600859021,
+ "582": 14789991457132928060
+}
diff --git a/assets/security/client_secret_key.ec2b b/assets/security/client_secret_key.ec2b
new file mode 100644
index 0000000..0dc6234
Binary files /dev/null and b/assets/security/client_secret_key.ec2b differ
diff --git a/nap_common/Cargo.toml b/nap_common/Cargo.toml
new file mode 100644
index 0000000..f833e6d
--- /dev/null
+++ b/nap_common/Cargo.toml
@@ -0,0 +1,33 @@
+[package]
+name = "common"
+edition = "2021"
+version.workspace = true
+
+[dependencies]
+# Serialization
+serde.workspace = true
+toml.workspace = true
+
+# Cryptography
+password-hash.workspace = true
+pbkdf2.workspace = true
+rsa.workspace = true
+rand_mt.workspace = true
+
+# Database
+sqlx.workspace = true
+
+# Util
+thiserror.workspace = true
+rand.workspace = true
+byteorder.workspace = true
+regex.workspace = true
+ansi_term.workspace = true
+
+# Logging
+env_logger.workspace = true
+tracing.workspace = true
+tracing-futures.workspace = true
+tracing-log.workspace = true
+tracing-subscriber.workspace = true
+tracing-bunyan-formatter.workspace = true
diff --git a/nap_common/client_public_key.der b/nap_common/client_public_key.der
new file mode 100644
index 0000000..1782ab2
Binary files /dev/null and b/nap_common/client_public_key.der differ
diff --git a/nap_common/migrations/0001_tables.sql b/nap_common/migrations/0001_tables.sql
new file mode 100644
index 0000000..ebc1f4b
--- /dev/null
+++ b/nap_common/migrations/0001_tables.sql
@@ -0,0 +1,26 @@
+CREATE TABLE t_sdk_account (
+ uid int primary key generated always as identity,
+ token varchar(64) NOT NULL,
+ username varchar(40) NOT NULL,
+ password varchar(256) NOT NULL,
+ UNIQUE(username)
+);
+
+CREATE TABLE t_combo_token (
+ account_uid varchar(32) primary key,
+ token varchar(64) NOT NULL,
+ device_id varchar(128) NOT NULL,
+ UNIQUE(account_uid, device_id)
+);
+
+CREATE TABLE t_user_uid (
+ uid int primary key generated always as identity,
+ account_uid varchar(64) NOT NULL,
+ ext varchar(512) NOT NULL DEFAULT '',
+ UNIQUE(account_uid)
+);
+
+CREATE TABLE t_player_data (
+ uid int primary key,
+ bin_data bytea NOT NULL
+);
diff --git a/nap_common/server_private_key.der b/nap_common/server_private_key.der
new file mode 100644
index 0000000..019d91b
Binary files /dev/null and b/nap_common/server_private_key.der differ
diff --git a/nap_common/src/constants.rs b/nap_common/src/constants.rs
new file mode 100644
index 0000000..0ca7466
--- /dev/null
+++ b/nap_common/src/constants.rs
@@ -0,0 +1,2 @@
+pub const SERVER_VERSION: &str = "0.1.0";
+pub const CLIENT_VERSION: &str = "CNBeta1.1.1";
diff --git a/nap_common/src/cryptography/ec2b/magic.rs b/nap_common/src/cryptography/ec2b/magic.rs
new file mode 100644
index 0000000..477632a
--- /dev/null
+++ b/nap_common/src/cryptography/ec2b/magic.rs
@@ -0,0 +1,536 @@
+#![allow(unused)]
+
+pub const SHIFT_ROWS_TABLE: [u8; 16] = [0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11];
+pub const SHIFT_ROWS_TABLE_INV: [u8; 16] = [0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3];
+pub const LOOKUP_RCON: [u8; 16] = [
+ 0x8d, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c, 0xd8, 0xab, 0x4d, 0x9a,
+];
+pub const LOOKUP_SBOX: [u8; 256] = [
+ 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
+ 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
+ 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
+ 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
+ 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
+ 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
+ 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
+ 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
+ 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
+ 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
+ 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
+ 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
+ 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
+ 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
+ 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
+ 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16,
+];
+pub const LOOKUP_SBOX_INV: [u8; 256] = [
+ 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
+ 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
+ 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
+ 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
+ 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
+ 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
+ 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
+ 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
+ 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
+ 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
+ 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
+ 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
+ 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
+ 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
+ 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
+ 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d,
+];
+pub const LOOKUP_G2: [u8; 256] = [
+ 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
+ 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
+ 0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
+ 0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
+ 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
+ 0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
+ 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
+ 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
+ 0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
+ 0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25,
+ 0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45,
+ 0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
+ 0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85,
+ 0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5,
+ 0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
+ 0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5,
+];
+pub const LOOKUP_G3: [u8; 256] = [
+ 0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
+ 0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
+ 0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
+ 0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41,
+ 0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1,
+ 0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,
+ 0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1,
+ 0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81,
+ 0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,
+ 0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba,
+ 0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea,
+ 0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,
+ 0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a,
+ 0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a,
+ 0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
+ 0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a,
+];
+pub const LOOKUP_G9: [u8; 256] = [
+ 0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
+ 0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7,
+ 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
+ 0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc,
+ 0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49, 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01,
+ 0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91,
+ 0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a,
+ 0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2, 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa,
+ 0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b,
+ 0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b,
+ 0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8, 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0,
+ 0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30,
+ 0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed,
+ 0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d,
+ 0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
+ 0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46,
+];
+pub const LOOKUP_G11: [u8; 256] = [
+ 0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69,
+ 0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9,
+ 0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
+ 0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2,
+ 0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7, 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f,
+ 0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f,
+ 0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4,
+ 0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c, 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54,
+ 0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e,
+ 0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e,
+ 0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd, 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5,
+ 0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55,
+ 0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68,
+ 0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8,
+ 0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
+ 0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3,
+];
+pub const LOOKUP_G13: [u8; 256] = [
+ 0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b,
+ 0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b,
+ 0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
+ 0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20,
+ 0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e, 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26,
+ 0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6,
+ 0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d,
+ 0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25, 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d,
+ 0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91,
+ 0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41,
+ 0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42, 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a,
+ 0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa,
+ 0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc,
+ 0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c,
+ 0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
+ 0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97,
+];
+pub const LOOKUP_G14: [u8; 256] = [
+ 0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a,
+ 0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba,
+ 0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
+ 0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61,
+ 0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87, 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7,
+ 0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17,
+ 0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c,
+ 0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc, 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc,
+ 0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b,
+ 0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb,
+ 0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0, 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0,
+ 0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20,
+ 0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6,
+ 0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56,
+ 0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
+ 0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d,
+];
+pub const KEY_XORPAD_TABLE: [u8; 16] = [
+ 0xA2, 0x25, 0x25, 0x99, 0xB7, 0x62, 0xF4, 0x39, 0x28, 0xE1, 0xB7, 0x73, 0x91, 0x05, 0x25, 0x87,
+];
+pub const AES_XORPAD_TABLE: [[u8; 2816]; 2] = [
+ [
+ 0xDE, 0xAD, 0xCA, 0xFE, 0xFA, 0xCE, 0xB0, 0x0C, 0xDE, 0xAD, 0xCA, 0xFE, 0xFA, 0xCE, 0xB0,
+ 0x0C, 0x3A, 0xE6, 0xDE, 0x9C, 0x81, 0xBA, 0x7C, 0xC6, 0x12, 0x1B, 0xAF, 0xD2, 0x8A, 0xBA,
+ 0xF5, 0xE6, 0x41, 0xDF, 0x71, 0xBA, 0x37, 0x11, 0x50, 0xF3, 0xF3, 0x62, 0x6E, 0x04, 0xF1,
+ 0x14, 0xFC, 0xBD, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE7, 0x7B, 0x52, 0x7C,
+ 0x19, 0x98, 0x35, 0x96, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0,
+ 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6,
+ 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81,
+ 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A,
+ 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A,
+ 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB,
+ 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A,
+ 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1,
+ 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA,
+ 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE,
+ 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0,
+ 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B,
+ 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC,
+ 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71,
+ 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25,
+ 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E,
+ 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76,
+ 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18,
+ 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E,
+ 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69,
+ 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47,
+ 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62,
+ 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8,
+ 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0,
+ 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3,
+ 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E,
+ 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48,
+ 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33,
+ 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78,
+ 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B,
+ 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E,
+ 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71,
+ 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53,
+ 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA,
+ 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18,
+ 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5,
+ 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0,
+ 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82,
+ 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73,
+ 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2,
+ 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE,
+ 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7,
+ 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F,
+ 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C,
+ 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2,
+ 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E,
+ 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF,
+ 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC,
+ 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E,
+ 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00,
+ 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8,
+ 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92,
+ 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35,
+ 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93,
+ 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67,
+ 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C,
+ 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC,
+ 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6,
+ 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2,
+ 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56,
+ 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37,
+ 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A,
+ 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA,
+ 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9,
+ 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0,
+ 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6,
+ 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81,
+ 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A,
+ 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A,
+ 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB,
+ 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A,
+ 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1,
+ 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA,
+ 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE,
+ 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0,
+ 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B,
+ 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC,
+ 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71,
+ 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25,
+ 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E,
+ 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76,
+ 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18,
+ 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E,
+ 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69,
+ 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47,
+ 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62,
+ 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8,
+ 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0,
+ 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3,
+ 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E,
+ 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48,
+ 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33,
+ 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78,
+ 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B,
+ 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E,
+ 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71,
+ 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53,
+ 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA,
+ 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18,
+ 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5,
+ 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0,
+ 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82,
+ 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73,
+ 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2,
+ 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE,
+ 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7,
+ 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F,
+ 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C,
+ 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2,
+ 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E,
+ 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF,
+ 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC,
+ 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E,
+ 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00,
+ 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8,
+ 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92,
+ 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35,
+ 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93,
+ 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67,
+ 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C,
+ 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC,
+ 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6,
+ 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2,
+ 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56,
+ 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37,
+ 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A,
+ 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA,
+ 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9,
+ 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0,
+ 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6,
+ 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81,
+ 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A,
+ 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A,
+ 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB,
+ 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A,
+ 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1,
+ 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA,
+ 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE,
+ 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0,
+ 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B,
+ 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC,
+ 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71,
+ 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25,
+ 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E,
+ 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76,
+ 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18,
+ 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E,
+ 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69,
+ 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47,
+ 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62,
+ 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8,
+ 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0,
+ 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3,
+ 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E,
+ 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48,
+ 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33,
+ 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78,
+ 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B,
+ 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E,
+ 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71,
+ 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53,
+ 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA,
+ 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18,
+ 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5,
+ 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0,
+ 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82,
+ 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73,
+ 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2,
+ 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE,
+ 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7,
+ 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F,
+ 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C,
+ 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2,
+ 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E,
+ 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF,
+ 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92, 0x18, 0x18, 0xE0, 0xAC,
+ 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35, 0xB5, 0x0E, 0xB6, 0x3E,
+ 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93, 0xD0, 0x69, 0x81, 0x00,
+ 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67, 0x82, 0x47, 0x6A, 0xB8,
+ 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56, 0x1F, 0x8E, 0xFA, 0x3C, 0x73, 0x62, 0x6A, 0x92,
+ 0x18, 0x18, 0xE0, 0xAC, 0x9E, 0x71, 0x37, 0x3C, 0x48, 0xDE, 0xDC, 0xA2, 0xE8, 0xBB, 0x35,
+ 0xB5, 0x0E, 0xB6, 0x3E, 0x71, 0x25, 0x8A, 0xF2, 0x33, 0xE0, 0xD6, 0xBE, 0xF0, 0x3A, 0x93,
+ 0xD0, 0x69, 0x81, 0x00, 0x53, 0x7E, 0xCA, 0x4E, 0x78, 0x4B, 0xA2, 0xF7, 0xB3, 0xF1, 0x67,
+ 0x82, 0x47, 0x6A, 0xB8, 0xAA, 0x76, 0xF9, 0xDF, 0x3B, 0xEC, 0x56,
+ ],
+ [
+ 0xC3, 0x20, 0x20, 0xB4, 0xAF, 0x0E, 0x82, 0x2E, 0xEF, 0x29, 0xFE, 0x75, 0x1D, 0xDB, 0x4B,
+ 0x86, 0x86, 0x23, 0x28, 0x72, 0xA3, 0xF4, 0x1B, 0x4F, 0x5F, 0x0E, 0x02, 0xB1, 0xAC, 0x0D,
+ 0xE6, 0x4F, 0x8B, 0x0B, 0x3F, 0xF3, 0x5F, 0xB5, 0x09, 0x7E, 0x3B, 0xE9, 0x93, 0x29, 0x55,
+ 0xE1, 0xB4, 0x9B, 0xCC, 0xCE, 0x37, 0xFC, 0xAB, 0x6B, 0xA4, 0x05, 0xE6, 0xC7, 0x45, 0x34,
+ 0xC0, 0xFF, 0x7C, 0x24, 0x89, 0x36, 0xBF, 0x17, 0xAB, 0x91, 0xCA, 0x49, 0xF2, 0x74, 0x80,
+ 0xB6, 0x90, 0x60, 0xFF, 0xD2, 0xA9, 0xE5, 0xC9, 0x64, 0xBC, 0x38, 0x40, 0x98, 0xB3, 0xBA,
+ 0x8F, 0x8B, 0xBA, 0x9D, 0xF3, 0xCF, 0x57, 0xBA, 0xAC, 0x18, 0xE7, 0xD3, 0x03, 0x01, 0x48,
+ 0x29, 0x41, 0xF6, 0x2F, 0x89, 0xD4, 0x9F, 0xD7, 0xD3, 0x05, 0x71, 0x63, 0x30, 0x4E, 0xBB,
+ 0xF7, 0xB0, 0x99, 0xFF, 0x43, 0xDA, 0x87, 0xCA, 0xA7, 0x48, 0x92, 0x9E, 0x76, 0xA6, 0xEE,
+ 0x48, 0x1C, 0x96, 0x28, 0x8E, 0x54, 0x30, 0xD6, 0xA5, 0xD3, 0x22, 0xA2, 0x30, 0xCB, 0x6A,
+ 0x85, 0x26, 0x69, 0xE1, 0x7C, 0xEC, 0xDC, 0xD4, 0x89, 0x2A, 0xB8, 0xAE, 0xDF, 0x12, 0x6E,
+ 0x39, 0x8A, 0x9B, 0x48, 0x61, 0xF9, 0x4B, 0x34, 0xD0, 0xF1, 0x60, 0x87, 0xBA, 0x88, 0x86,
+ 0x68, 0x8C, 0xBE, 0xC1, 0x9C, 0xAE, 0x30, 0xBC, 0xE6, 0x62, 0xFF, 0xEB, 0xBB, 0x88, 0x7C,
+ 0xD2, 0xBB, 0x57, 0xB4, 0x02, 0x82, 0x06, 0x72, 0xD2, 0x94, 0x60, 0x86, 0x4A, 0x29, 0xF0,
+ 0xEA, 0xD3, 0x88, 0x92, 0xF1, 0x22, 0xD1, 0x5C, 0x88, 0x65, 0xE6, 0xFB, 0xEE, 0x28, 0x79,
+ 0x86, 0x68, 0x7D, 0xA6, 0x5A, 0xBF, 0xBD, 0x7D, 0x15, 0xEF, 0x05, 0xF6, 0xF9, 0xE0, 0x11,
+ 0xD6, 0x30, 0x94, 0xF2, 0x6C, 0x3D, 0x0A, 0xDB, 0xC5, 0x0E, 0xDC, 0xF2, 0xFD, 0x1F, 0x61,
+ 0x91, 0x5D, 0x80, 0x69, 0xA3, 0xDB, 0x35, 0x98, 0x4E, 0x4A, 0xC1, 0x49, 0x76, 0xAB, 0xC0,
+ 0x67, 0x36, 0x3F, 0xA4, 0xC6, 0xE8, 0xCA, 0x25, 0x44, 0x63, 0x23, 0xB5, 0xC8, 0xBB, 0x3A,
+ 0xAC, 0xA1, 0x09, 0xC3, 0x10, 0x57, 0xA5, 0x5B, 0x3B, 0x33, 0x21, 0xCD, 0x3C, 0x88, 0xAE,
+ 0x1E, 0x8F, 0xC1, 0xD6, 0xFB, 0x94, 0x61, 0x38, 0xAB, 0xF1, 0x9C, 0x06, 0xCB, 0x89, 0x58,
+ 0x9A, 0xF4, 0xF4, 0x33, 0x80, 0x66, 0x13, 0xC0, 0xFD, 0xE2, 0x16, 0xE0, 0x89, 0x65, 0xE2,
+ 0xC1, 0xA6, 0xE3, 0x74, 0xD2, 0x5F, 0xA0, 0x76, 0xAD, 0xF5, 0x6B, 0x4F, 0xE0, 0xF7, 0x52,
+ 0xB0, 0xB1, 0x48, 0xDD, 0xEE, 0xB6, 0x01, 0x9A, 0x90, 0x91, 0x18, 0xEC, 0xCB, 0xCB, 0xAD,
+ 0x04, 0xB6, 0x73, 0xCF, 0x7F, 0xF3, 0xAC, 0xBE, 0xEC, 0x91, 0x44, 0x56, 0x81, 0xB8, 0x74,
+ 0xAE, 0x28, 0x5D, 0xC7, 0x5C, 0xAB, 0x8B, 0x56, 0x21, 0x32, 0x91, 0xB9, 0x9E, 0x70, 0xF6,
+ 0x9B, 0xAC, 0x50, 0x0B, 0x2E, 0x4B, 0x8B, 0xA2, 0xA5, 0x24, 0x5B, 0x91, 0xDF, 0x24, 0xA7,
+ 0xB0, 0x79, 0xA7, 0x16, 0x54, 0x44, 0x2E, 0xBC, 0x48, 0xCD, 0x87, 0xBA, 0xAF, 0xD4, 0xB9,
+ 0x1C, 0x0F, 0xAA, 0xFA, 0x3A, 0x3F, 0x3A, 0x3D, 0x68, 0x5A, 0xAE, 0xAC, 0xBA, 0xBE, 0xA3,
+ 0x92, 0x6E, 0x38, 0x8E, 0x33, 0x3E, 0x0A, 0xCC, 0xF6, 0xE3, 0x26, 0x57, 0xEC, 0x8E, 0x63,
+ 0x31, 0x27, 0xBA, 0x20, 0x4E, 0x7F, 0x34, 0xE5, 0x19, 0xFE, 0x7F, 0xA6, 0x97, 0x90, 0xD6,
+ 0x29, 0x1C, 0x3F, 0x8C, 0x3F, 0x81, 0x62, 0x3D, 0xF5, 0x00, 0xD4, 0xC5, 0xE2, 0xE1, 0x42,
+ 0x42, 0x8C, 0x65, 0x8F, 0x5A, 0x66, 0x59, 0xE1, 0xDD, 0xEC, 0xDC, 0x1B, 0x4E, 0x63, 0x82,
+ 0xFF, 0x02, 0x9D, 0x53, 0xDE, 0xBD, 0xB4, 0x80, 0xCF, 0x2B, 0xB7, 0xDE, 0x69, 0x5D, 0x1B,
+ 0xCA, 0xFB, 0xB3, 0xF9, 0xBE, 0xD0, 0xF5, 0x79, 0x86, 0x2F, 0x0E, 0xB6, 0xA9, 0x87, 0xF4,
+ 0x68, 0xC1, 0xBF, 0x4F, 0xB8, 0xA6, 0x2D, 0x03, 0xA9, 0x72, 0x04, 0xCA, 0x37, 0x6D, 0x1B,
+ 0x90, 0xDD, 0xBC, 0x52, 0xAE, 0xF3, 0xFF, 0x08, 0xDD, 0x4B, 0x46, 0xD0, 0xCD, 0xB1, 0x8A,
+ 0x35, 0x9A, 0x02, 0x64, 0x64, 0x2F, 0x57, 0xA5, 0x7B, 0x9A, 0x0D, 0x2B, 0x55, 0x11, 0x3C,
+ 0xC0, 0x35, 0x74, 0x69, 0xD9, 0x7B, 0x43, 0x1D, 0xAC, 0xB2, 0xC2, 0x8A, 0xBE, 0x22, 0x45,
+ 0x46, 0x76, 0xA9, 0x8A, 0x49, 0xB2, 0x5F, 0xC0, 0xB8, 0xBC, 0xCD, 0x27, 0xF8, 0x14, 0xB2,
+ 0xA9, 0x6D, 0x5A, 0x1F, 0xA4, 0x43, 0x1E, 0x0F, 0xDB, 0xA4, 0x9E, 0x2B, 0xCA, 0xFC, 0x98,
+ 0x7F, 0xF1, 0x18, 0x87, 0x5B, 0x11, 0x2D, 0xC5, 0xE4, 0x91, 0x20, 0xA9, 0x6A, 0x2D, 0xAC,
+ 0xA8, 0xFA, 0x94, 0x57, 0x7F, 0x30, 0x73, 0x08, 0xE8, 0x49, 0xF0, 0xC8, 0x63, 0xDA, 0x83,
+ 0x87, 0x2A, 0xC3, 0x31, 0x1A, 0xFC, 0xB7, 0x57, 0xB2, 0x40, 0x46, 0x09, 0x6D, 0x84, 0xB4,
+ 0x66, 0xF1, 0x13, 0x16, 0x3A, 0x3A, 0xFB, 0xC6, 0x6E, 0xB0, 0x71, 0xB8, 0x23, 0x74, 0x22,
+ 0x89, 0xFC, 0xBE, 0x34, 0xB3, 0x17, 0xB6, 0xC9, 0x68, 0x53, 0x64, 0x47, 0xAF, 0xCA, 0x1D,
+ 0x5F, 0xB4, 0x74, 0xA3, 0x77, 0xB5, 0xFB, 0x77, 0xD9, 0x69, 0x2B, 0x3A, 0xAA, 0xAE, 0xE4,
+ 0x03, 0x81, 0x6B, 0x3A, 0x35, 0x9C, 0x45, 0x50, 0x9C, 0x76, 0xCE, 0xE3, 0x7F, 0x64, 0x4B,
+ 0x9F, 0x83, 0x7B, 0x72, 0xBC, 0x02, 0x1E, 0x94, 0x99, 0xC1, 0x1C, 0x45, 0x19, 0x1D, 0x56,
+ 0x74, 0x73, 0xE7, 0xFC, 0x58, 0x72, 0x2D, 0xE3, 0x50, 0xA4, 0x21, 0xBE, 0x81, 0xDF, 0x80,
+ 0xDA, 0x40, 0xDB, 0x79, 0x67, 0x0E, 0x94, 0xA3, 0x05, 0xDD, 0xF7, 0x14, 0x28, 0xD6, 0xC4,
+ 0x2B, 0xF3, 0xCF, 0x36, 0x08, 0x84, 0xF3, 0xC8, 0x8C, 0xAD, 0xCE, 0x7F, 0x7C, 0x0F, 0xC6,
+ 0xFE, 0x05, 0x54, 0x4B, 0x17, 0xA1, 0x83, 0x65, 0x97, 0x29, 0x01, 0x70, 0xC1, 0x16, 0xAE,
+ 0x69, 0xA4, 0x90, 0xB9, 0xBE, 0x17, 0x05, 0x50, 0xF1, 0x65, 0x07, 0x23, 0x76, 0x64, 0x84,
+ 0x2D, 0x40, 0x34, 0xFD, 0xDF, 0x62, 0x7E, 0x4C, 0x85, 0xD2, 0x6D, 0x17, 0xE1, 0x41, 0x12,
+ 0xC6, 0x3E, 0xD6, 0x14, 0xB8, 0x5F, 0x8F, 0x39, 0x65, 0xC2, 0x62, 0x21, 0x06, 0x5C, 0xC9,
+ 0xB8, 0x99, 0xA5, 0x00, 0xE3, 0x9C, 0x73, 0xAB, 0xB9, 0x76, 0x12, 0xD2, 0xFA, 0x7F, 0x7D,
+ 0x64, 0x63, 0x9E, 0x26, 0xAA, 0x89, 0x85, 0x3A, 0xC9, 0x94, 0x04, 0x97, 0xEC, 0xFD, 0xC5,
+ 0xA3, 0xB1, 0x7D, 0xD6, 0x07, 0x9C, 0x47, 0x30, 0x9C, 0x64, 0x97, 0x0E, 0xC6, 0xFC, 0x0B,
+ 0xFF, 0xA7, 0xF9, 0x46, 0x5B, 0x2B, 0xDB, 0x9E, 0x1C, 0x85, 0x3A, 0x75, 0xD6, 0xEB, 0x9B,
+ 0x15, 0x36, 0xD7, 0x1A, 0x3D, 0xFC, 0x0B, 0x75, 0x08, 0x5E, 0x32, 0x23, 0xE0, 0xA5, 0xAD,
+ 0x0F, 0x45, 0xB3, 0x78, 0x20, 0x22, 0x24, 0x64, 0x0C, 0xCF, 0xD6, 0x3C, 0xA4, 0x48, 0xC7,
+ 0xB3, 0x6E, 0x02, 0xE2, 0x0A, 0xAB, 0x92, 0xFC, 0x40, 0x7D, 0xF5, 0x02, 0x61, 0x56, 0xAB,
+ 0xC5, 0x68, 0x38, 0xE0, 0x01, 0xF1, 0x94, 0x73, 0xC6, 0xFE, 0xC2, 0x34, 0x67, 0x8E, 0xB1,
+ 0x73, 0x72, 0xD4, 0x3B, 0xFD, 0x1F, 0xE2, 0xA8, 0xED, 0x20, 0x14, 0x0A, 0x60, 0x6D, 0xD1,
+ 0x85, 0x14, 0x05, 0x54, 0x96, 0xC6, 0x3D, 0xB5, 0x1B, 0x37, 0x56, 0x24, 0xF7, 0x7C, 0x0F,
+ 0x55, 0xC6, 0xAA, 0x7E, 0x33, 0x2D, 0xE1, 0x97, 0x74, 0xA8, 0xDC, 0xC5, 0xA1, 0xEC, 0x8C,
+ 0xEF, 0x28, 0x3B, 0x49, 0x8B, 0x00, 0xED, 0x8B, 0xD9, 0xE9, 0x65, 0xD5, 0x05, 0x7B, 0x6D,
+ 0x20, 0xCA, 0x8F, 0x93, 0xB4, 0xCA, 0x36, 0x34, 0x8E, 0x16, 0x46, 0xCE, 0x02, 0x23, 0x43,
+ 0x22, 0xF6, 0xBD, 0x10, 0xCC, 0xD0, 0xA3, 0xB0, 0x42, 0xA5, 0xAF, 0x59, 0x72, 0x97, 0x0B,
+ 0xAE, 0x80, 0x8D, 0x19, 0xD0, 0x1D, 0x7D, 0x30, 0x4E, 0x5B, 0x46, 0xC0, 0xC2, 0x5C, 0x40,
+ 0xFC, 0xF3, 0xEF, 0x05, 0x84, 0xE8, 0x0C, 0x80, 0xD7, 0x37, 0xA1, 0x6F, 0xC1, 0x8C, 0xE0,
+ 0xBA, 0xA1, 0x88, 0x7B, 0xE7, 0x20, 0xBF, 0x18, 0x02, 0x40, 0x9F, 0x6F, 0x23, 0x11, 0x78,
+ 0x07, 0xD0, 0x92, 0x87, 0x2D, 0xB5, 0xE0, 0xE9, 0xE9, 0xAA, 0x32, 0x88, 0x57, 0xF8, 0x9B,
+ 0x01, 0x93, 0x2D, 0x07, 0x77, 0x68, 0x86, 0xAD, 0x06, 0xDE, 0x57, 0xA9, 0xA4, 0x96, 0x33,
+ 0x42, 0xF8, 0xFB, 0x23, 0x1F, 0x99, 0xB6, 0x62, 0x93, 0x6B, 0x12, 0xBE, 0x72, 0x9F, 0x96,
+ 0x1A, 0xDA, 0x05, 0x60, 0xF1, 0xD5, 0x40, 0x9F, 0x75, 0xF3, 0x1D, 0xBE, 0xD7, 0x87, 0x5D,
+ 0x3A, 0x55, 0xF0, 0x9B, 0xBF, 0xE8, 0xB9, 0x72, 0xC2, 0xDD, 0x4D, 0x27, 0xF6, 0xA9, 0x37,
+ 0x96, 0x7E, 0x6E, 0x6E, 0x64, 0x37, 0x4E, 0x2E, 0x3F, 0xFD, 0x3C, 0xF4, 0xA6, 0xF5, 0x22,
+ 0xA8, 0x43, 0xF4, 0x13, 0x21, 0xB5, 0x4E, 0xA8, 0x6D, 0x50, 0x0A, 0xB3, 0xFE, 0x9F, 0x5C,
+ 0xE7, 0x1A, 0xCF, 0x36, 0x42, 0x30, 0x1C, 0x88, 0x7F, 0x29, 0xE9, 0xCD, 0x96, 0xF2, 0x6A,
+ 0x52, 0xB2, 0x25, 0x87, 0x63, 0xDC, 0xFC, 0x72, 0xE4, 0xF8, 0x5E, 0xB1, 0x97, 0xB4, 0x1E,
+ 0x08, 0x90, 0x68, 0x10, 0x73, 0x7F, 0x94, 0x61, 0x48, 0x49, 0x36, 0x9B, 0x7D, 0xBD, 0xDF,
+ 0xCD, 0xB1, 0xA3, 0x7D, 0xFB, 0xDD, 0x97, 0x8A, 0x0D, 0xFC, 0x9A, 0xB8, 0xA9, 0x33, 0xB5,
+ 0x4E, 0x50, 0x3D, 0x60, 0x90, 0xEB, 0xAB, 0xB8, 0xCB, 0x6E, 0x32, 0xE4, 0x6B, 0xB0, 0x3F,
+ 0x57, 0xB8, 0xA4, 0x6A, 0x7C, 0x00, 0x66, 0x39, 0xB1, 0x22, 0xE2, 0x04, 0x26, 0xA1, 0x5A,
+ 0x17, 0xAA, 0x80, 0xB6, 0xC0, 0xF6, 0xCF, 0x7A, 0xF8, 0x60, 0xE9, 0x52, 0xB8, 0x0E, 0x08,
+ 0xC0, 0xD5, 0x1F, 0xAB, 0x61, 0x62, 0x1A, 0x83, 0xD1, 0x92, 0xE1, 0x4D, 0x6D, 0xDF, 0x27,
+ 0x0E, 0xFF, 0xF9, 0xA3, 0x36, 0xFF, 0x73, 0xEF, 0x1D, 0xAB, 0xAC, 0xBF, 0xA7, 0xB3, 0x29,
+ 0xD2, 0xB2, 0x37, 0xAB, 0x08, 0x7D, 0xB6, 0x7E, 0x0D, 0x25, 0xAA, 0x49, 0x29, 0x9F, 0x61,
+ 0x52, 0x44, 0x19, 0x1C, 0x51, 0x95, 0x74, 0xB9, 0x3D, 0xDD, 0x95, 0x2C, 0x4F, 0x30, 0x56,
+ 0xC9, 0xEF, 0x3D, 0x87, 0x90, 0x1E, 0xF8, 0x69, 0xFF, 0x37, 0x06, 0x27, 0xDB, 0x72, 0x82,
+ 0x2C, 0xDE, 0xB8, 0x39, 0x0B, 0x78, 0xB1, 0x1F, 0x37, 0x54, 0xBF, 0x21, 0x32, 0x87, 0xB4,
+ 0xD9, 0x49, 0x2D, 0x29, 0x19, 0x43, 0x01, 0xD4, 0xC0, 0xA3, 0xFF, 0x09, 0x6F, 0x69, 0xC8,
+ 0x5D, 0x35, 0x1D, 0x10, 0x09, 0x91, 0xB6, 0x12, 0xEC, 0x04, 0xA6, 0x61, 0xEF, 0x73, 0xC7,
+ 0x4C, 0x04, 0x8E, 0x3E, 0xAE, 0xD7, 0xC2, 0x84, 0x48, 0xAB, 0x99, 0x96, 0x75, 0xD8, 0xAD,
+ 0xA7, 0x5B, 0xDE, 0x72, 0x44, 0x96, 0xC5, 0xB3, 0xEB, 0x8E, 0xED, 0xD6, 0x69, 0x81, 0xE6,
+ 0x07, 0x3A, 0x15, 0x0D, 0x66, 0x5F, 0x36, 0xA9, 0xAB, 0x53, 0x82, 0x47, 0x98, 0x27, 0xF2,
+ 0x16, 0x95, 0x05, 0x0B, 0xAE, 0xF1, 0x04, 0x92, 0x80, 0x20, 0xA4, 0x9B, 0x43, 0x66, 0x70,
+ 0x7F, 0x45, 0x0B, 0x4B, 0x85, 0x95, 0x10, 0x09, 0xC8, 0xD9, 0xF9, 0x5D, 0x40, 0x6D, 0x07,
+ 0x69, 0x18, 0xF3, 0xD6, 0x98, 0x61, 0x25, 0x8E, 0xA1, 0xE2, 0x24, 0xBD, 0xF0, 0xFA, 0x89,
+ 0xD8, 0x68, 0xB2, 0x03, 0x81, 0x63, 0xF9, 0x42, 0xD4, 0x1A, 0xD9, 0x4D, 0xCD, 0x30, 0x36,
+ 0x2D, 0xB1, 0x63, 0xFC, 0xA3, 0x2B, 0xA7, 0x07, 0x50, 0xBC, 0x67, 0xAB, 0x7D, 0x33, 0x1D,
+ 0xEC, 0x62, 0xFE, 0xD2, 0x65, 0xAA, 0xBA, 0x37, 0xC9, 0x7F, 0x67, 0x26, 0x9D, 0x8A, 0x8B,
+ 0x63, 0x0B, 0xE0, 0x30, 0x65, 0x07, 0x8C, 0xF3, 0xD1, 0xCF, 0x0D, 0xB4, 0x1E, 0xF3, 0x29,
+ 0xBE, 0x43, 0x1F, 0x34, 0x1E, 0x52, 0x02, 0xA7, 0x8D, 0x30, 0x2E, 0x3E, 0x39, 0x00, 0xB6,
+ 0x7B, 0x5C, 0x29, 0x39, 0xC0, 0x0D, 0xAB, 0xA0, 0x6D, 0x77, 0x3C, 0xB2, 0x18, 0x42, 0x57,
+ 0x63, 0xDA, 0x9E, 0xF5, 0xE0, 0x42, 0x43, 0xF6, 0x50, 0xFD, 0x71, 0x9B, 0x30, 0xE0, 0x92,
+ 0x8B, 0xD1, 0xE1, 0xC4, 0x96, 0xC9, 0xF5, 0x14, 0xB6, 0xF7, 0xA5, 0x10, 0x77, 0xF4, 0xF9,
+ 0xAC, 0xDC, 0x45, 0xE1, 0x3C, 0xD6, 0x0B, 0xA5, 0xE2, 0x58, 0x01, 0x19, 0x39, 0x14, 0x68,
+ 0x96, 0xC0, 0xCE, 0xA9, 0xDE, 0x84, 0x22, 0x59, 0x87, 0x70, 0xFD, 0x8A, 0x71, 0x64, 0x79,
+ 0x16, 0x37, 0x80, 0x83, 0xFD, 0x9C, 0x73, 0xE6, 0x9C, 0x8B, 0xCD, 0xC0, 0x69, 0x66, 0x90,
+ 0x45, 0x0A, 0xC9, 0x81, 0x4A, 0xDA, 0x26, 0xDA, 0xA1, 0x70, 0x03, 0x6C, 0x36, 0x9D, 0xAD,
+ 0xD7, 0xE2, 0x1F, 0x27, 0xBE, 0xBB, 0xEC, 0x63, 0xD9, 0xC2, 0x2A, 0x56, 0x4D, 0x63, 0xCD,
+ 0x92, 0xEE, 0xAF, 0xCA, 0xD0, 0x11, 0x35, 0x2F, 0x1D, 0xF1, 0x96, 0xD1, 0xAA, 0xDC, 0xF6,
+ 0x14, 0x3F, 0xA0, 0xEE, 0x90, 0x83, 0x9F, 0x42, 0x40, 0xE6, 0x2C, 0x10, 0x23, 0x00, 0x23,
+ 0x18, 0x8C, 0xA1, 0x26, 0x4B, 0x22, 0xE1, 0x36, 0x07, 0x55, 0xCB, 0xC3, 0xD2, 0xDD, 0x12,
+ 0x58, 0x19, 0x75, 0x03, 0xC6, 0xD8, 0x2E, 0xCE, 0x87, 0x1C, 0xC3, 0x15, 0x44, 0x2A, 0x30,
+ 0x00, 0x52, 0x39, 0x31, 0x13, 0xF4, 0x25, 0x75, 0x74, 0x15, 0x6C, 0xC5, 0xC1, 0xD2, 0x33,
+ 0x75, 0xC2, 0x41, 0x22, 0x28, 0x95, 0xDF, 0x97, 0x6C, 0x31, 0xF8, 0x35, 0xA6, 0x54, 0x29,
+ 0x5C, 0xF4, 0x20, 0x97, 0x69, 0xE5, 0x46, 0xFF, 0x34, 0x24, 0x73, 0x12, 0xB8, 0x61, 0x25,
+ 0x46, 0xB3, 0x8F, 0xBA, 0x3C, 0xFA, 0x06, 0xFF, 0x3F, 0x66, 0x9D, 0x22, 0x55, 0x46, 0x2F,
+ 0xFF, 0x44, 0xDB, 0x25, 0x29, 0xE0, 0x16, 0x6E, 0xEC, 0x87, 0x97, 0x92, 0x37, 0x23, 0x0E,
+ 0x52, 0x4E, 0xBB, 0x10, 0xBB, 0x1C, 0x73, 0x75, 0xD1, 0x31, 0xC3, 0xAD, 0xFE, 0xB8, 0x12,
+ 0x50, 0xA0, 0x69, 0x91, 0x36, 0xEA, 0x5F, 0x0D, 0xEC, 0x1A, 0x23, 0x4A, 0x7D, 0x94, 0x84,
+ 0xC8, 0x4A, 0x58, 0x6A, 0xA1, 0xA3, 0x75, 0xCA, 0x85, 0xE7, 0x96, 0x91, 0x07, 0x05, 0x3A,
+ 0x57, 0x61, 0x6A, 0x6F, 0xF1, 0xEF, 0xF7, 0xB3, 0xB1, 0x09, 0xB8, 0x91, 0xA8, 0xF9, 0x57,
+ 0xB8, 0x63, 0x95, 0xFF, 0xB4, 0x1C, 0x96, 0xE7, 0xE5, 0xEC, 0x06, 0x3A, 0x11, 0xE6, 0x81,
+ 0xAB, 0x23, 0xE4, 0x5E, 0x5A, 0xB6, 0x6B, 0x69, 0x62, 0x6F, 0x9D, 0xC4, 0x08, 0x6F, 0xA6,
+ 0xBE, 0x4D, 0x09, 0x12, 0x77, 0xCA, 0xDD, 0xB5, 0x2D, 0x66, 0xCB, 0x4F, 0x4F, 0x11, 0xF2,
+ 0x3A, 0x1A, 0x97, 0x1F, 0xFE, 0x50, 0x2F, 0x19, 0x32, 0x05, 0x45, 0xA0, 0x50, 0x60, 0x58,
+ 0x40, 0x40, 0x3D, 0xF6, 0xC3, 0x6F, 0x07, 0xC8, 0x26, 0x26, 0x0E, 0x42, 0x22, 0x96, 0x6D,
+ 0xFE, 0x95, 0x53, 0x70, 0xDC, 0x92, 0x12, 0x63, 0xFD, 0xA3, 0x7D, 0x6E, 0x44, 0xCD, 0x11,
+ 0x2C, 0x51, 0x6F, 0xBC, 0x50, 0xFC, 0x1C, 0xC8, 0x3A, 0x28, 0xF5, 0x39, 0xF8, 0x8C, 0x60,
+ 0x5D, 0xA5, 0x4A, 0xFA, 0xAB, 0x04, 0x7F, 0x34, 0x91, 0x53, 0xE7, 0x6C, 0x56, 0xC6, 0x14,
+ 0xE4, 0xCC, 0xE4, 0xBB, 0x6E, 0x47, 0x7A, 0x46, 0x6B, 0xE2, 0x88, 0xA0, 0xBD, 0xBD, 0xCC,
+ 0x51, 0xF3, 0x37, 0x4B, 0xB3, 0xA0, 0x19, 0x92, 0x48, 0x35, 0xBB, 0xBC, 0x79, 0x78, 0xFF,
+ 0x49, 0xC1, 0x2B, 0x93, 0xDF, 0x75, 0xA7, 0xFB, 0x94, 0x89, 0xAF, 0x50, 0x5E, 0x2D, 0xE1,
+ 0x78, 0x60, 0x0C, 0xDF, 0xF8, 0x7C, 0xFD, 0xCD, 0x2D, 0xE2, 0xFF, 0xD3, 0xA3, 0x4A, 0x48,
+ 0x0D, 0x40, 0x8F, 0x03, 0x4F, 0x2C, 0xBD, 0xFA, 0x2E, 0x16, 0xC3, 0xD4, 0xFD, 0x0B, 0xB3,
+ 0xBD, 0x4F, 0x30, 0xAD, 0xD0, 0xAE, 0xCA, 0x77, 0x9D, 0xDD, 0x3D, 0xA3, 0x66, 0xD0, 0xC1,
+ 0x6D, 0xCC, 0x3B, 0x56, 0x81, 0x5D, 0x80, 0x07, 0xD8, 0x84, 0x46, 0x71, 0x40, 0x57, 0xB3,
+ 0x44, 0x85, 0x63, 0x4E, 0x17, 0x2C, 0xB0, 0x21, 0x98, 0x43, 0x42, 0x04, 0x18, 0x84, 0xFA,
+ 0xB1, 0xD7, 0xC5, 0x5C, 0xCA, 0x25, 0x8B, 0x1A, 0x7A, 0x50, 0x60, 0x68, 0x4A, 0x30, 0xEA,
+ 0xE6, 0xDE, 0x19, 0xBB, 0x9F, 0x47, 0xEF, 0xDB, 0xC5, 0x81, 0x72, 0xF0, 0x8D, 0xBA, 0x74,
+ 0x3A, 0xD1, 0xD5, 0xC6, 0xD1, 0xE0, 0xAE, 0x28, 0x2A, 0x65, 0xE5, 0x0B, 0x09, 0xFA, 0xEA,
+ 0x5B, 0xA6, 0xDB, 0x38, 0xD8, 0x67, 0xC0, 0xBE, 0xA1, 0x12, 0x1C, 0x03, 0xB1, 0x81, 0xB8,
+ 0x95, 0xDD, 0x78, 0xF8, 0x16, 0x6E, 0xAB, 0xBB, 0xAA, 0x33, 0x54, 0x0E, 0x39, 0x83, 0x24,
+ 0x17, 0xB3, 0x0B, 0x3C, 0xA1, 0x62, 0x21, 0xB2, 0xA0, 0xF8, 0x49, 0xAB, 0x8B, 0x80, 0xC6,
+ 0x3D, 0xF1, 0x2E, 0x18, 0x44, 0x74, 0x5F, 0x98, 0x92, 0x33, 0xFB, 0xB2, 0x52, 0x6B, 0x97,
+ 0xE9, 0x48, 0x12, 0x91, 0x32, 0x50, 0x21, 0x75, 0x74, 0x69, 0x88, 0x54, 0xC6, 0xF3, 0xC9,
+ 0x37, 0x3C, 0xB3, 0x89, 0xAB, 0x33, 0x1F, 0x79, 0x57, 0xF7, 0xE4, 0xB5, 0x87, 0x0C, 0xA4,
+ 0x99, 0x48, 0x89, 0x63, 0x5F, 0x72, 0xA1, 0xBC, 0xFF, 0xFE, 0xF8, 0xB3, 0xF1, 0x00, 0xE4,
+ 0xD4, 0x01, 0x9B, 0xB7, 0x2E, 0x4F, 0xA0, 0x90, 0xE4, 0x9B, 0x6A, 0xA8, 0xBA, 0xE1, 0xD3,
+ 0xD5, 0xBC, 0xEB, 0xC5, 0xB2, 0x89, 0xB4, 0xE9, 0x4D, 0x3F, 0x4C, 0xFA, 0x8C, 0xCB, 0xCD,
+ 0x22, 0x08, 0xB8, 0xC7, 0xB3, 0xA3, 0xED, 0x6B, 0xAC, 0xF3, 0x2D, 0x98, 0x70, 0x41, 0x47,
+ 0x85, 0xE8, 0x6E, 0x31, 0x0A, 0xC2, 0x3E, 0x51, 0x39, 0x55, 0xF8, 0x4A, 0xE9, 0x48, 0x64,
+ 0x01, 0xDB, 0x8D, 0xE3, 0xAF, 0xA4, 0xB9, 0xD8, 0x19, 0xCA, 0x86, 0xCA, 0xA1, 0x6C, 0x1C,
+ 0x12, 0x3D, 0xA1, 0x02, 0x23, 0x1D, 0x29, 0x5D, 0x94, 0x04, 0xC6, 0x51, 0x01, 0x40, 0x0B,
+ 0xB3, 0x69, 0x25, 0x45, 0xEF, 0x43, 0x81, 0x4F, 0x97, 0x57, 0x0D, 0xA1, 0xA5, 0xC9, 0x9D,
+ 0xE6, 0x56, 0xB9, 0x38, 0x93, 0xA1, 0x78, 0xC5, 0xBF, 0x75, 0xFE, 0x81, 0x6A, 0x35, 0x64,
+ 0x89, 0x64, 0x43, 0x75, 0xFD, 0x29, 0x63, 0xD1, 0x15, 0xAB, 0x43, 0x60, 0x65, 0xDC, 0x98,
+ 0xD5, 0xC7, 0x6E, 0xF9, 0xB2, 0x38, 0xFB, 0x6E, 0xB0, 0x34, 0x9C, 0xA3, 0x73, 0x61, 0xF5,
+ 0x51, 0xFF, 0x1F, 0xCE, 0xB0, 0x08, 0x83, 0x29, 0xB3, 0x82, 0x07, 0xFA, 0xC4, 0xE5, 0x21,
+ 0xD3, 0xA0, 0xD4, 0xC0, 0xF8, 0x1A, 0x65, 0x9B, 0x35, 0x7A, 0xE3, 0x32, 0xA5, 0x4D, 0x77,
+ 0x1F, 0x23, 0x19, 0xCC, 0xE1, 0xB3, 0x50, 0x0D, 0xE8, 0x2F, 0x8B, 0x18, 0x89, 0x61, 0xCB,
+ 0x22, 0xBA, 0xE0, 0x4A, 0xA2, 0x7F, 0xA5, 0x1B, 0x45, 0x59, 0x33, 0xC4, 0x73, 0xDF, 0x42,
+ 0xC6, 0x00, 0x11, 0x37, 0xF2, 0x3C, 0x1B, 0xF4, 0x26, 0xD1, 0x6D, 0x93, 0xC1, 0x94, 0xD2,
+ 0x60, 0xE5, 0xF3, 0x91, 0x66, 0x92, 0x3C, 0x65, 0x27, 0xC1, 0x83, 0x13, 0x76, 0x5A, 0x88,
+ 0xEC, 0xB2, 0x59, 0x95, 0x18, 0x81, 0x2E, 0x94, 0x96, 0x53, 0x17, 0xB6, 0xFD, 0x8C, 0xCC,
+ 0xBE, 0x8D, 0x36, 0xB3, 0xC8, 0xF2, 0xB2, 0xBE, 0x0F, 0x12, 0x99, 0xFF, 0xFA, 0xF9, 0x18,
+ 0xAB, 0x30, 0xFA, 0xB1, 0x5B, 0xF2, 0xEE, 0xCA, 0x6E, 0xA1, 0xD9, 0xCE, 0xCC, 0x60, 0xA0,
+ 0x4D, 0xFD, 0x7C, 0xAD, 0x4D, 0x50, 0xB6, 0x88, 0x0D, 0x88, 0x3B, 0x28, 0x7F, 0xA1, 0x28,
+ 0x41, 0x0A, 0x43, 0xAD, 0xCC, 0x08, 0x14, 0xF3, 0xF2, 0x43, 0xE7, 0xCF, 0x6A, 0x5C, 0x11,
+ 0xD0, 0x6D, 0x99, 0xC8, 0x4F, 0xB1, 0x14, 0x06, 0xBC, 0x68, 0x6D, 0xBE, 0xCD, 0xD7, 0x58,
+ 0xA2, 0x17, 0xF5, 0x9E, 0xFD, 0xDA, 0xFA, 0xBF, 0x73, 0x57, 0x4A, 0xF8, 0xF3, 0xA9, 0x94,
+ 0xB3, 0x01, 0xE9, 0xA3, 0xDA, 0xEA, 0xC1, 0x40, 0x33, 0xAA, 0x3F, 0xE6, 0x0D, 0x6A, 0xE2,
+ 0xF3, 0x74, 0xE8, 0x1B, 0x3C, 0x2B, 0x25, 0x44, 0x8E, 0x1C, 0x36, 0xBE, 0xA9, 0x27, 0x6E,
+ 0x6A, 0x48, 0x8E, 0x2F, 0x2C, 0x9D, 0x71, 0x66, 0x23, 0x7C, 0x7A, 0x74, 0x93, 0x46, 0x2D,
+ 0xCA, 0x6B, 0xC6, 0x33, 0xDA, 0x1E, 0x1E, 0x44, 0x07, 0xFD, 0x89, 0x5D, 0x30, 0x02, 0x4C,
+ 0xB1, 0x73, 0xC0, 0x91, 0xEB, 0xA5, 0x61, 0x89, 0xA4, 0x04, 0xFD, 0xD5, 0x5F, 0x54, 0x59,
+ 0x81, 0xC3, 0x2A, 0x13, 0x89, 0xDA, 0x68, 0xB6, 0x3A, 0x9C, 0x70, 0x6F, 0x48, 0xB4, 0x3C,
+ 0xF8, 0x9B, 0xF8, 0xF2, 0x59, 0xBF, 0xF4, 0x8D, 0x06, 0x58, 0xEA, 0xA2, 0xA6, 0xB4, 0x70,
+ 0x08, 0x80, 0x2B, 0x50, 0x13, 0x36, 0x79, 0x17, 0x0B, 0x94, 0x0E, 0x4D, 0xF5, 0xC8, 0x14,
+ 0xB9, 0x02, 0x7D, 0xEE, 0x6B, 0xBD, 0x10, 0xB4, 0x85, 0x74, 0xA1, 0xB9, 0x84, 0x67, 0xC6,
+ 0x2C, 0xDB, 0xDA, 0x55, 0x54, 0x16, 0xDA, 0x02, 0xB6, 0xDA, 0x2A, 0x9B, 0x51, 0xD6, 0xDC,
+ 0x87, 0x80, 0xC1, 0xB8, 0x6F, 0x0C, 0xEF, 0x4B, 0xD1, 0x1A, 0x9F, 0x36, 0x2E, 0x9C, 0x7E,
+ 0x5F, 0x17, 0xE2, 0xC1, 0x82, 0x0C, 0x42, 0x0D, 0x15, 0x18, 0xCA,
+ ],
+];
diff --git a/nap_common/src/cryptography/ec2b/mhy_aes.rs b/nap_common/src/cryptography/ec2b/mhy_aes.rs
new file mode 100644
index 0000000..2b6f5c1
--- /dev/null
+++ b/nap_common/src/cryptography/ec2b/mhy_aes.rs
@@ -0,0 +1,175 @@
+#![allow(unused)]
+
+use super::magic::{LOOKUP_G11, LOOKUP_G13, LOOKUP_G14, LOOKUP_G2, LOOKUP_G3, LOOKUP_G9, LOOKUP_RCON, LOOKUP_SBOX, LOOKUP_SBOX_INV, SHIFT_ROWS_TABLE, SHIFT_ROWS_TABLE_INV};
+
+fn xorr(a: &mut [u8], b: &[u8], n: usize) {
+ (0..n).for_each(|i| a[i] ^= b[i]);
+}
+
+fn xor_round_key(state: &mut [u8], keys: &[u8], round: usize) {
+ xorr(state, &keys[round * 16..], 16);
+}
+
+fn sub_bytes(a: &mut [u8], n: usize) {
+ (0..n).for_each(|i| a[i] = LOOKUP_SBOX[a[i] as usize]);
+}
+
+fn sub_bytes_inv(a: &mut [u8], n: usize) {
+ (0..n).for_each(|i| a[i] = LOOKUP_SBOX_INV[a[i] as usize]);
+}
+
+fn key_schedule_core(a: &mut [u8], i: usize) {
+ let temp = a[0];
+ a[0] = a[1];
+ a[1] = a[2];
+ a[2] = a[3];
+ a[3] = temp;
+ sub_bytes(a, 4);
+ a[0] ^= LOOKUP_RCON[i];
+}
+
+fn oqs_aes128_load_schedule_c(key: &[u8]) -> [u8; 176] {
+ let mut schedule = [0u8; 176];
+
+ let mut bytes = 16;
+ let mut i = 1;
+ let mut t = [0u8; 4];
+
+ schedule[0..16].copy_from_slice(key);
+
+ while bytes < 176 {
+ t.copy_from_slice(&schedule[bytes - 4..]);
+ key_schedule_core(&mut t, i);
+ i += 1;
+ xorr(&mut schedule[bytes..], &t, 4);
+ schedule[bytes..].copy_from_slice(&t);
+ bytes += 4;
+
+ for _ in 0..3 {
+ t.copy_from_slice(&schedule[bytes - 4..]);
+ xorr(&mut t, &schedule[bytes - 16..], 4);
+ schedule[bytes..].copy_from_slice(&t);
+ bytes += 4;
+ }
+ }
+
+ schedule
+}
+
+fn shift_rows(state: &mut [u8]) {
+ let temp = state.to_vec();
+ (0..16).for_each(|i| state[i] = temp[SHIFT_ROWS_TABLE[i] as usize]);
+}
+
+fn shift_rows_inv(state: &mut [u8]) {
+ let temp = state.to_vec();
+ (0..16).for_each(|i| state[i] = temp[SHIFT_ROWS_TABLE_INV[i] as usize]);
+}
+
+fn mix_col(state: &mut [u8]) {
+ let (a0, a1, a2, a3) = (state[0], state[1], state[2], state[3]);
+
+ state[0] = LOOKUP_G2[a0 as usize] ^ LOOKUP_G3[a1 as usize] ^ a2 ^ a3;
+ state[1] = LOOKUP_G2[a1 as usize] ^ LOOKUP_G3[a2 as usize] ^ a3 ^ a0;
+ state[2] = LOOKUP_G2[a2 as usize] ^ LOOKUP_G3[a3 as usize] ^ a0 ^ a1;
+ state[3] = LOOKUP_G2[a3 as usize] ^ LOOKUP_G3[a0 as usize] ^ a1 ^ a2;
+}
+
+fn mix_cols(state: &mut [u8]) {
+ mix_col(&mut state[0..4]);
+ mix_col(&mut state[4..8]);
+ mix_col(&mut state[8..12]);
+ mix_col(&mut state[12..16]);
+}
+
+fn mix_col_inv(state: &mut [u8]) {
+ let (a0, a1, a2, a3) = (state[0], state[1], state[2], state[3]);
+
+ state[0] = LOOKUP_G14[a0 as usize]
+ ^ LOOKUP_G9[a3 as usize]
+ ^ LOOKUP_G13[a2 as usize]
+ ^ LOOKUP_G11[a1 as usize];
+ state[1] = LOOKUP_G14[a1 as usize]
+ ^ LOOKUP_G9[a0 as usize]
+ ^ LOOKUP_G13[a3 as usize]
+ ^ LOOKUP_G11[a2 as usize];
+ state[2] = LOOKUP_G14[a2 as usize]
+ ^ LOOKUP_G9[a1 as usize]
+ ^ LOOKUP_G13[a0 as usize]
+ ^ LOOKUP_G11[a3 as usize];
+ state[3] = LOOKUP_G14[a3 as usize]
+ ^ LOOKUP_G9[a2 as usize]
+ ^ LOOKUP_G13[a1 as usize]
+ ^ LOOKUP_G11[a0 as usize];
+}
+
+fn mix_cols_inv(state: &mut [u8]) {
+ mix_col_inv(&mut state[0..4]);
+ mix_col_inv(&mut state[4..8]);
+ mix_col_inv(&mut state[8..12]);
+ mix_col_inv(&mut state[12..16]);
+}
+
+fn oqs_aes128_enc_c(plaintext: &[u8], schedule: &[u8], ciphertext: &mut [u8]) {
+ ciphertext.copy_from_slice(&plaintext[..16]);
+ xor_round_key(ciphertext, schedule, 0);
+
+ for i in 1..10 {
+ sub_bytes(ciphertext, 16);
+ shift_rows(ciphertext);
+ mix_cols(ciphertext);
+ xor_round_key(ciphertext, schedule, i);
+ }
+
+ sub_bytes(ciphertext, 16);
+ shift_rows(ciphertext);
+ xor_round_key(ciphertext, schedule, 10);
+}
+
+pub fn oqs_mhy128_enc_c(plaintext: &[u8], schedule: &[u8], ciphertext: &mut [u8]) {
+ ciphertext.copy_from_slice(&plaintext[..16]);
+ xor_round_key(ciphertext, schedule, 0);
+
+ for i in 1..10 {
+ sub_bytes_inv(ciphertext, 16);
+ shift_rows_inv(ciphertext);
+ mix_cols_inv(ciphertext);
+ xor_round_key(ciphertext, schedule, i);
+ }
+
+ sub_bytes_inv(ciphertext, 16);
+ shift_rows_inv(ciphertext);
+ xor_round_key(ciphertext, schedule, 10);
+}
+
+fn oqs_aes128_dec_c(ciphertext: &[u8], schedule: &[u8], plaintext: &mut [u8]) {
+ plaintext.copy_from_slice(&ciphertext[..16]);
+ xor_round_key(plaintext, schedule, 10);
+ shift_rows_inv(plaintext);
+ sub_bytes_inv(plaintext, 16);
+
+ for i in 0..9 {
+ xor_round_key(plaintext, schedule, 9 - i);
+ mix_cols_inv(plaintext);
+ shift_rows_inv(plaintext);
+ sub_bytes_inv(plaintext, 16);
+ }
+
+ xor_round_key(plaintext, schedule, 0);
+}
+
+fn oqs_mhy128_dec_c(ciphertext: &[u8], schedule: &[u8], plaintext: &mut [u8]) {
+ plaintext.copy_from_slice(&ciphertext[..16]);
+ xor_round_key(plaintext, schedule, 10);
+ shift_rows(plaintext);
+ sub_bytes(plaintext, 16);
+
+ for i in 0..9 {
+ xor_round_key(plaintext, schedule, 9 - i);
+ mix_cols(plaintext);
+ shift_rows(plaintext);
+ sub_bytes(plaintext, 16);
+ }
+
+ xor_round_key(plaintext, schedule, 0);
+}
diff --git a/nap_common/src/cryptography/ec2b/mod.rs b/nap_common/src/cryptography/ec2b/mod.rs
new file mode 100644
index 0000000..a6d062e
--- /dev/null
+++ b/nap_common/src/cryptography/ec2b/mod.rs
@@ -0,0 +1,92 @@
+use byteorder::{BigEndian, LittleEndian, ReadBytesExt};
+use magic::{AES_XORPAD_TABLE, KEY_XORPAD_TABLE};
+use mhy_aes::oqs_mhy128_enc_c;
+use std::io::Read;
+use thiserror::Error;
+
+mod magic;
+mod mhy_aes;
+
+const HEAD_MAGIC: u32 = 0x45633262; // "Ec2b"
+const KEY_SIZE: usize = 16;
+const DATA_SIZE: usize = 2048;
+
+pub struct Ec2b {
+ key: [u8; KEY_SIZE],
+ data: [u8; DATA_SIZE],
+}
+
+#[derive(Error, Debug)]
+pub enum DecodeError {
+ #[error("an I/O error occurred: {0}")]
+ IoError(#[from] std::io::Error),
+ #[error("magic mismatch, expected: {HEAD_MAGIC}, got: {0}")]
+ MagicMismatch(u32),
+ #[error("invalid key size, expected: {KEY_SIZE}, got: {0}")]
+ InvalidKeySize(usize),
+ #[error("invalid data size, expected: {DATA_SIZE}, got: {0}")]
+ InvalidDataSize(usize),
+}
+
+impl Ec2b {
+ const XOR_MAGIC: u64 = 0xCEAC3B5A867837AC;
+
+ pub fn read(r: &mut R) -> Result {
+ let magic = r.read_u32::()?;
+ matches!(magic, HEAD_MAGIC)
+ .then_some(())
+ .ok_or(DecodeError::MagicMismatch(magic))?;
+
+ let key_size = r.read_u32::()? as usize;
+ matches!(key_size, KEY_SIZE)
+ .then_some(())
+ .ok_or(DecodeError::InvalidKeySize(key_size))?;
+
+ let mut key = [0u8; KEY_SIZE];
+ r.read_exact(&mut key)?;
+
+ let data_size = r.read_u32::()? as usize;
+ matches!(data_size, DATA_SIZE)
+ .then_some(())
+ .ok_or(DecodeError::InvalidDataSize(data_size))?;
+
+ let mut data = [0u8; DATA_SIZE];
+ r.read_exact(&mut data)?;
+
+ Self::key_scramble(&mut key);
+ (0..16).for_each(|i| key[i] ^= KEY_XORPAD_TABLE[i]);
+
+ Ok(Self { key, data })
+ }
+
+ #[must_use] pub fn derive_seed(&self) -> u64 {
+ let val = self
+ .data
+ .chunks_exact(8)
+ .map(|chunk| u64::from_le_bytes(chunk.try_into().unwrap()))
+ .fold(0xFFFFFFFFFFFFFFFF, |val, i| val ^ i);
+
+ let key_qword_0 = u64::from_le_bytes(self.key[0..8].try_into().unwrap());
+ let key_qword_1 = u64::from_le_bytes(self.key[8..16].try_into().unwrap());
+
+ key_qword_1 ^ Self::XOR_MAGIC ^ val ^ key_qword_0
+ }
+
+ fn key_scramble(key: &mut [u8]) {
+ let mut round_keys = [0u8; 176];
+ for round in 0..11 {
+ for i in 0..16 {
+ for j in 0..16 {
+ let idx = (round << 8) + (i * 16) + j;
+ round_keys[round * 16 + i] ^=
+ AES_XORPAD_TABLE[1][idx] ^ AES_XORPAD_TABLE[0][idx];
+ }
+ }
+ }
+
+ let mut chip = [0u8; 16];
+ oqs_mhy128_enc_c(key, &round_keys, &mut chip);
+
+ key.copy_from_slice(&chip);
+ }
+}
diff --git a/nap_common/src/cryptography/mod.rs b/nap_common/src/cryptography/mod.rs
new file mode 100644
index 0000000..2c16a94
--- /dev/null
+++ b/nap_common/src/cryptography/mod.rs
@@ -0,0 +1,7 @@
+mod ec2b;
+mod rsa_util;
+mod xor;
+
+pub use ec2b::Ec2b;
+pub use rsa_util::*;
+pub use xor::MhyXorpad;
diff --git a/nap_common/src/cryptography/rsa_util.rs b/nap_common/src/cryptography/rsa_util.rs
new file mode 100644
index 0000000..5bbfee7
--- /dev/null
+++ b/nap_common/src/cryptography/rsa_util.rs
@@ -0,0 +1,48 @@
+use rsa::pkcs1v15::SigningKey;
+use rsa::sha2::Sha256;
+use rsa::signature::{RandomizedSigner, SignatureEncoding};
+use rsa::{Pkcs1v15Encrypt, RsaPrivateKey, RsaPublicKey};
+
+const CLIENT_PUBLIC_KEY: &[u8] = include_bytes!("../../client_public_key.der");
+const SERVER_PRIVATE_KEY: &[u8] = include_bytes!("../../server_private_key.der");
+const RSA_CHUNK_SIZE: usize = 117;
+
+#[must_use]
+pub fn rsa_encrypt(data: &[u8]) -> Box<[u8]> {
+ let public_key: RsaPublicKey =
+ rsa::pkcs8::DecodePublicKey::from_public_key_der(CLIENT_PUBLIC_KEY)
+ .expect("Failed to read public key from der");
+ let mut rng = rand::thread_rng();
+
+ let mut result: Vec = Vec::new();
+ for chunk in data.chunks(RSA_CHUNK_SIZE) {
+ let encrypted_chunk = public_key
+ .encrypt(&mut rng, Pkcs1v15Encrypt, chunk)
+ .expect("Encryption failed");
+
+ result.extend(encrypted_chunk);
+ }
+
+ result.into()
+}
+
+#[must_use]
+pub fn rsa_decrypt(cipher: &[u8]) -> Vec {
+ let private_key: RsaPrivateKey =
+ rsa::pkcs8::DecodePrivateKey::from_pkcs8_der(SERVER_PRIVATE_KEY)
+ .expect("Failed to read pkcs8 private key");
+
+ private_key
+ .decrypt(Pkcs1v15Encrypt, cipher)
+ .expect("Decryption failed")
+}
+
+#[must_use]
+pub fn rsa_sign(data: &[u8]) -> Box<[u8]> {
+ let private_key = rsa::pkcs8::DecodePrivateKey::from_pkcs8_der(SERVER_PRIVATE_KEY)
+ .expect("Failed to read pkcs8 private key");
+ let signing_key = SigningKey::::new(private_key);
+
+ let mut rng = rand::thread_rng();
+ signing_key.sign_with_rng(&mut rng, data).to_bytes()
+}
diff --git a/nap_common/src/cryptography/xor.rs b/nap_common/src/cryptography/xor.rs
new file mode 100644
index 0000000..7bcffb6
--- /dev/null
+++ b/nap_common/src/cryptography/xor.rs
@@ -0,0 +1,22 @@
+use byteorder::ByteOrder;
+use rand_mt::Mt64;
+
+const SIZE: usize = 4096;
+pub struct MhyXorpad([u8; SIZE]);
+
+impl MhyXorpad {
+ #[must_use]
+ pub fn new(seed: u64) -> Self {
+ let mut mt = Mt64::new(seed);
+ let mut buf = [0u8; 4096];
+
+ (0..(SIZE >> 3)).for_each(|i| E::write_u64(&mut buf[i * 8..(i + 1) * 8], mt.next_u64()));
+ Self(buf)
+ }
+
+ pub fn xor(&self, buf: &mut [u8]) {
+ buf.iter_mut()
+ .enumerate()
+ .for_each(|(i, v)| *v ^= self.0[i % SIZE]);
+ }
+}
diff --git a/nap_common/src/database/mod.rs b/nap_common/src/database/mod.rs
new file mode 100644
index 0000000..a6f3057
--- /dev/null
+++ b/nap_common/src/database/mod.rs
@@ -0,0 +1,40 @@
+use serde::{Deserialize, Serialize};
+use sqlx::{migrate, PgPool};
+
+pub mod player_data;
+pub mod sdk_data;
+
+#[derive(Serialize, Deserialize)]
+pub struct DatabaseCredentials {
+ pub username: String,
+ pub password: String,
+ pub host: String,
+ pub name: String,
+}
+
+impl ToString for DatabaseCredentials {
+ fn to_string(&self) -> String {
+ format!(
+ "postgres://{}:{}@{}/{}",
+ &self.username, &self.password, &self.host, &self.name
+ )
+ }
+}
+
+impl Default for DatabaseCredentials {
+ fn default() -> Self {
+ Self {
+ username: String::from("root"),
+ password: String::from("root"),
+ host: String::from("localhost:5432"),
+ name: String::from("nap"),
+ }
+ }
+}
+
+pub async fn init(credentials: &DatabaseCredentials) -> Result {
+ let pool = PgPool::connect(&credentials.to_string()).await?;
+ migrate!("./migrations").run(&pool).await?;
+
+ Ok(pool)
+}
diff --git a/nap_common/src/database/player_data.rs b/nap_common/src/database/player_data.rs
new file mode 100644
index 0000000..d7bdce1
--- /dev/null
+++ b/nap_common/src/database/player_data.rs
@@ -0,0 +1,20 @@
+use serde::{Deserialize, Serialize};
+use sqlx::FromRow;
+
+#[derive(FromRow, Debug)]
+pub struct DbUserUidRow {
+ pub uid: i32,
+ pub account_uid: String,
+ pub ext: String,
+}
+
+#[derive(FromRow, Debug)]
+pub struct DbPlayerDataRow {
+ pub uid: i32,
+ pub bin_data: Vec,
+}
+
+#[derive(Serialize, Deserialize)]
+pub struct PlayerExtJsonData {
+ pub reg_platform: u32,
+}
diff --git a/nap_common/src/database/sdk_data.rs b/nap_common/src/database/sdk_data.rs
new file mode 100644
index 0000000..86bcfdc
--- /dev/null
+++ b/nap_common/src/database/sdk_data.rs
@@ -0,0 +1,97 @@
+use std::sync::LazyLock;
+
+use regex::Regex;
+use sqlx::FromRow;
+
+use thiserror::Error;
+
+use crate::util;
+
+#[derive(sqlx::Encode, sqlx::Decode)]
+pub struct Username(String);
+
+impl Username {
+ pub fn parse(username: String) -> Option {
+ static ALLOWED_USERNAME_REGEX: LazyLock =
+ LazyLock::new(|| Regex::new("^[a-zA-Z0-9._@-]{6,25}$").unwrap());
+
+ ALLOWED_USERNAME_REGEX
+ .is_match(&username)
+ .then_some(Self(username))
+ }
+
+ pub fn as_str(&self) -> &str {
+ self.0.as_str()
+ }
+}
+
+impl sqlx::Type for Username {
+ fn type_info() -> ::TypeInfo {
+ >::type_info()
+ }
+
+ fn compatible(ty: &::TypeInfo) -> bool {
+ >::compatible(ty)
+ }
+}
+
+#[derive(Error, Debug)]
+pub enum PasswordError {
+ #[error("password pair mismatch")]
+ PairMismatch,
+ #[error("user input doesn't meet requirements")]
+ RequirementsMismatch,
+ #[error("failed to generate password hash: {0}")]
+ HashFailed(pbkdf2::password_hash::Error),
+}
+
+#[derive(sqlx::Encode, sqlx::Decode)]
+pub struct Password(String);
+
+impl Password {
+ pub fn new(password: String, password_v2: String) -> Result {
+ (password == password_v2)
+ .then_some(())
+ .ok_or(PasswordError::PairMismatch)?;
+
+ matches!(password.len(), 8..30)
+ .then_some(())
+ .ok_or(PasswordError::RequirementsMismatch)?;
+
+ let hash = util::hash_string(&password).map_err(|err| PasswordError::HashFailed(err))?;
+ Ok(Self(hash))
+ }
+
+ pub fn verify(&self, password: &str) -> bool {
+ util::verify_hash(password, &self.0).is_some()
+ }
+
+ pub fn as_hash_str(&self) -> &str {
+ self.0.as_str()
+ }
+}
+
+impl sqlx::Type for Password {
+ fn type_info() -> ::TypeInfo {
+ >::type_info()
+ }
+
+ fn compatible(ty: &::TypeInfo) -> bool {
+ >::compatible(ty)
+ }
+}
+
+#[derive(FromRow)]
+pub struct DbSdkAccountRow {
+ pub uid: i32,
+ pub token: String,
+ pub username: Username,
+ pub password: Password,
+}
+
+#[derive(FromRow)]
+pub struct DbComboTokenRow {
+ pub account_uid: String,
+ pub token: String,
+ pub device_id: String,
+}
diff --git a/nap_common/src/lib.rs b/nap_common/src/lib.rs
new file mode 100644
index 0000000..d69d389
--- /dev/null
+++ b/nap_common/src/lib.rs
@@ -0,0 +1,8 @@
+pub mod constants;
+pub mod cryptography;
+pub mod database;
+mod logging;
+pub mod splash;
+pub mod util;
+
+pub use logging::init_tracing;
diff --git a/nap_common/src/logging.rs b/nap_common/src/logging.rs
new file mode 100644
index 0000000..3072a93
--- /dev/null
+++ b/nap_common/src/logging.rs
@@ -0,0 +1,6 @@
+pub fn init_tracing() {
+ #[cfg(target_os = "windows")]
+ ansi_term::enable_ansi_support().unwrap();
+
+ env_logger::init_from_env(env_logger::Env::new().default_filter_or("info"));
+}
diff --git a/nap_common/src/splash.rs b/nap_common/src/splash.rs
new file mode 100644
index 0000000..f0af59f
--- /dev/null
+++ b/nap_common/src/splash.rs
@@ -0,0 +1,5 @@
+use crate::constants::{CLIENT_VERSION, SERVER_VERSION};
+
+pub fn print(service_type: &str) {
+ println!("\n ____. ________ __________ _________\n | |____ ____ ____ \\______ \\ ____ ____ \\____ / / _____/\n | \\__ \\ / \\_/ __ \\ | | \\ / _ \\_/ __ \\ / / \\_____ \\ \n/\\__| |/ __ \\| | \\ ___/ | ` ( <_> ) ___/ / /_ / \\\n\\________(______/___|__/\\_____>_________/\\____/ \\_____> /_______/\\/________ /\n v{SERVER_VERSION} (game: {CLIENT_VERSION}) {service_type}\n");
+}
diff --git a/nap_common/src/util.rs b/nap_common/src/util.rs
new file mode 100644
index 0000000..54c43ec
--- /dev/null
+++ b/nap_common/src/util.rs
@@ -0,0 +1,67 @@
+use std::{
+ fs::File,
+ time::{SystemTime, UNIX_EPOCH},
+};
+
+use password_hash::{PasswordHash, PasswordHasher, SaltString};
+use pbkdf2::{Params, Pbkdf2};
+use serde::{de::DeserializeOwned, Serialize};
+
+#[must_use]
+pub fn load_or_create_config(path: &str) -> T
+where
+ T: Default + Serialize + DeserializeOwned,
+{
+ std::fs::read_to_string(path).map_or_else(
+ |_| {
+ let defaults = T::default();
+ std::fs::write(path, toml::to_string(&defaults).unwrap()).unwrap();
+ defaults
+ },
+ |data| toml::from_str(&data).unwrap(),
+ )
+}
+
+#[must_use]
+pub fn open_secret_key() -> Result {
+ File::open("assets/security/client_secret_key.ec2b")
+}
+
+#[must_use]
+pub fn cur_timestamp_ms() -> u64 {
+ SystemTime::now()
+ .duration_since(UNIX_EPOCH)
+ .unwrap()
+ .as_millis() as u64
+}
+
+#[must_use]
+pub fn cur_timestamp() -> u64 {
+ SystemTime::now()
+ .duration_since(UNIX_EPOCH)
+ .unwrap()
+ .as_secs() as u64
+}
+
+#[must_use]
+pub fn hash_string(content: &str) -> Result {
+ let salt = SaltString::generate(rand::thread_rng());
+ let hash = Pbkdf2.hash_password_customized(
+ content.as_bytes(),
+ None,
+ None,
+ Params {
+ rounds: 10000,
+ output_length: 32,
+ },
+ &salt,
+ )?;
+
+ Ok(hash.serialize().to_string())
+}
+
+#[must_use]
+pub fn verify_hash(content: &str, hash_str: &str) -> Option<()> {
+ let hash = PasswordHash::new(hash_str).ok()?;
+ hash.verify_password(&[&Pbkdf2], content).ok()
+}
diff --git a/nap_data/Cargo.toml b/nap_data/Cargo.toml
new file mode 100644
index 0000000..40486cc
--- /dev/null
+++ b/nap_data/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "data"
+edition = "2021"
+version.workspace = true
+
+[dependencies]
+# Serialization
+serde.workspace = true
+serde_json.workspace = true
+
+# Util
+paste.workspace = true
+thiserror.workspace = true
+
+# Tracing
+tracing.workspace = true
diff --git a/nap_data/src/lib.rs b/nap_data/src/lib.rs
new file mode 100644
index 0000000..967438b
--- /dev/null
+++ b/nap_data/src/lib.rs
@@ -0,0 +1,45 @@
+pub mod tables;
+
+use std::{collections::HashMap, sync::OnceLock};
+
+use serde::{Deserialize, Serialize};
+use thiserror::Error;
+
+#[derive(Serialize, Deserialize)]
+pub struct AssetsConfig {
+ pub filecfg_path: String,
+ pub usm_keys_path: String,
+}
+
+#[derive(Error, Debug)]
+pub enum DataLoadError {
+ #[error("I/O error: {0}")]
+ IoError(#[from] std::io::Error),
+ #[error("from_json failed for type {0}, error: {1}")]
+ FromJsonError(String, serde_json::Error),
+}
+
+static USM_KEY_MAP: OnceLock> = OnceLock::new();
+
+pub fn init_data(config: &AssetsConfig) -> Result<(), DataLoadError> {
+ tables::load_tables(&config.filecfg_path)?;
+ if let Err(err) = load_usm_keys(&config.usm_keys_path) {
+ tracing::warn!("failed to load USM keys, in-game cutscenes will not work! Reason: {err}");
+ USM_KEY_MAP.set(HashMap::new()).unwrap();
+ }
+
+ Ok(())
+}
+
+pub fn usm_key_map() -> &'static HashMap {
+ USM_KEY_MAP.get().unwrap()
+}
+
+fn load_usm_keys(path: &str) -> Result<(), DataLoadError> {
+ let data = std::fs::read_to_string(path).map_err(|err| DataLoadError::IoError(err))?;
+ let map = serde_json::from_str::>(&data)
+ .map_err(|err| DataLoadError::FromJsonError(String::from("USMKeyMap"), err))?;
+
+ USM_KEY_MAP.set(map).unwrap();
+ Ok(())
+}
diff --git a/nap_data/src/tables/avatar_base_template.rs b/nap_data/src/tables/avatar_base_template.rs
new file mode 100644
index 0000000..ea01361
--- /dev/null
+++ b/nap_data/src/tables/avatar_base_template.rs
@@ -0,0 +1,17 @@
+use serde::Deserialize;
+
+#[derive(Deserialize, Debug)]
+#[serde(rename_all = "PascalCase")]
+pub struct AvatarBaseTemplate {
+ #[serde(rename = "ID")]
+ pub id: u32,
+ pub code_name: String,
+ pub name: String,
+ pub full_name: String,
+ pub audio_event_replace_param: String,
+ pub audio_bank: String,
+ pub hit_types: Box<[u32]>,
+ pub element_types: Box<[u32]>,
+ pub gender: u32,
+ pub camp: u32,
+}
diff --git a/nap_data/src/tables/mod.rs b/nap_data/src/tables/mod.rs
new file mode 100644
index 0000000..ba3a498
--- /dev/null
+++ b/nap_data/src/tables/mod.rs
@@ -0,0 +1,46 @@
+use paste::paste;
+use std::sync::OnceLock;
+
+use super::DataLoadError;
+
+macro_rules! template_tables {
+ ($($template_type:ident;)*) => {
+ $(paste! {
+ mod [<$template_type:snake>];
+ pub use [<$template_type:snake>]::$template_type;
+ })*
+
+ $(paste! {
+ static [<$template_type:snake:upper _TB>]: OnceLock> = OnceLock::new();
+ })*
+
+ pub(crate) fn load_tables(filecfg_path: &str) -> Result<(), DataLoadError> {
+ $(paste! {
+ let file_name = concat!(stringify!($template_type), "Tb.json");
+ let path = format!("{filecfg_path}/{file_name}");
+
+ let data = std::fs::read_to_string(path)?;
+ [<$template_type:snake:upper _TB>].set(serde_json::from_str(&data).map_err(|err| DataLoadError::FromJsonError(String::from(stringify!($template_type)), err))?).unwrap();
+ })*
+
+ Ok(())
+ }
+
+ $(paste! {
+ pub mod [<$template_type:snake _tb>] {
+ pub fn iter() -> ::std::slice::Iter<'static, super::$template_type> {
+ super::[<$template_type:snake:upper _TB>].get().unwrap().iter()
+ }
+ }
+ })*
+ };
+}
+
+template_tables! {
+ AvatarBaseTemplate;
+ UnlockConfigTemplate;
+ SectionConfigTemplate;
+ ProcedureConfigTemplate;
+ PostGirlConfigTemplate;
+ TrainingQuestTemplate;
+}
diff --git a/nap_data/src/tables/post_girl_config_template.rs b/nap_data/src/tables/post_girl_config_template.rs
new file mode 100644
index 0000000..6ac70f6
--- /dev/null
+++ b/nap_data/src/tables/post_girl_config_template.rs
@@ -0,0 +1,9 @@
+use serde::Deserialize;
+
+#[derive(Deserialize, Debug)]
+#[serde(rename_all = "PascalCase")]
+pub struct PostGirlConfigTemplate {
+ #[serde(rename = "ID")]
+ pub id: u32,
+ pub name: String,
+}
diff --git a/nap_data/src/tables/procedure_config_template.rs b/nap_data/src/tables/procedure_config_template.rs
new file mode 100644
index 0000000..850d44c
--- /dev/null
+++ b/nap_data/src/tables/procedure_config_template.rs
@@ -0,0 +1,14 @@
+use serde::Deserialize;
+
+#[derive(Deserialize, Debug)]
+#[serde(rename_all = "PascalCase")]
+pub struct ProcedureConfigTemplate {
+ #[serde(rename = "ProcedureID")]
+ pub procedure_id: i32,
+ pub procedure_type: u32,
+ #[serde(rename = "ContentID")]
+ pub content_id: String,
+ pub jump_tos: Vec,
+ pub procedure_banks: Vec,
+ pub procedure_event: String,
+}
diff --git a/nap_data/src/tables/section_config_template.rs b/nap_data/src/tables/section_config_template.rs
new file mode 100644
index 0000000..d277c8f
--- /dev/null
+++ b/nap_data/src/tables/section_config_template.rs
@@ -0,0 +1,12 @@
+use serde::Deserialize;
+
+#[derive(Deserialize, Debug)]
+#[serde(rename_all = "PascalCase")]
+pub struct SectionConfigTemplate {
+ pub section_id: u32,
+ pub photo_name: String,
+ pub name: String,
+ pub primary_entry_name: String,
+ pub secondary_entry_name: String,
+ pub section_name: String,
+}
diff --git a/nap_data/src/tables/training_quest_template.rs b/nap_data/src/tables/training_quest_template.rs
new file mode 100644
index 0000000..028f363
--- /dev/null
+++ b/nap_data/src/tables/training_quest_template.rs
@@ -0,0 +1,9 @@
+use serde::Deserialize;
+
+#[derive(Deserialize, Debug)]
+#[serde(rename_all = "PascalCase")]
+pub struct TrainingQuestTemplate {
+ pub id: u32,
+ pub training_type: u32,
+ pub battle_event_id: u32,
+}
diff --git a/nap_data/src/tables/unlock_config_template.rs b/nap_data/src/tables/unlock_config_template.rs
new file mode 100644
index 0000000..083d434
--- /dev/null
+++ b/nap_data/src/tables/unlock_config_template.rs
@@ -0,0 +1,9 @@
+use serde::Deserialize;
+
+#[derive(Deserialize, Debug)]
+#[serde(rename_all = "PascalCase")]
+pub struct UnlockConfigTemplate {
+ #[serde(rename = "ID")]
+ pub id: i32,
+ pub name: String,
+}
diff --git a/nap_gameserver/Cargo.toml b/nap_gameserver/Cargo.toml
new file mode 100644
index 0000000..a8c5131
--- /dev/null
+++ b/nap_gameserver/Cargo.toml
@@ -0,0 +1,42 @@
+[package]
+name = "nap-gameserver"
+edition = "2021"
+version.workspace = true
+
+[dependencies]
+# Runtime
+tokio.workspace = true
+tokio-util.workspace = true
+
+# Serialization
+prost.workspace = true
+prost-types.workspace = true
+rbase64.workspace = true
+toml.workspace = true
+serde.workspace = true
+serde_json.workspace = true
+
+# Database
+sqlx.workspace = true
+
+# Util
+thiserror.workspace = true
+paste.workspace = true
+byteorder.workspace = true
+hex.workspace = true
+rand.workspace = true
+atomic_enum.workspace = true
+num_enum.workspace = true
+dashmap.workspace = true
+
+# Tracing
+tracing.workspace = true
+tracing-futures.workspace = true
+tracing-log.workspace = true
+tracing-subscriber.workspace = true
+tracing-bunyan-formatter.workspace = true
+
+# Internal
+common.workspace = true
+data.workspace = true
+proto.workspace = true
diff --git a/nap_gameserver/src/config.rs b/nap_gameserver/src/config.rs
new file mode 100644
index 0000000..e66068b
--- /dev/null
+++ b/nap_gameserver/src/config.rs
@@ -0,0 +1,26 @@
+use common::database::DatabaseCredentials;
+use data::AssetsConfig;
+use serde::{Deserialize, Serialize};
+
+#[derive(Serialize, Deserialize)]
+pub struct NapGSConfig {
+ pub tcp_listen_addr: String,
+ pub player_save_period_seconds: u64,
+ #[serde(rename = "database")]
+ pub database_credentials: DatabaseCredentials,
+ pub assets: AssetsConfig,
+}
+
+impl Default for NapGSConfig {
+ fn default() -> Self {
+ Self {
+ tcp_listen_addr: String::from("0.0.0.0:20501"),
+ player_save_period_seconds: 30,
+ database_credentials: DatabaseCredentials::default(),
+ assets: AssetsConfig {
+ filecfg_path: String::from("assets/FileCfg"),
+ usm_keys_path: String::from("assets/VideoUSMEncKeys.json"),
+ },
+ }
+ }
+}
diff --git a/nap_gameserver/src/database/mod.rs b/nap_gameserver/src/database/mod.rs
new file mode 100644
index 0000000..f84cc12
--- /dev/null
+++ b/nap_gameserver/src/database/mod.rs
@@ -0,0 +1,94 @@
+use common::database::{
+ player_data::{DbPlayerDataRow, DbUserUidRow, PlayerExtJsonData},
+ sdk_data::DbComboTokenRow,
+};
+use sqlx::{query, query_as, PgPool};
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+pub enum DbError {
+ #[error("SQL error: {0}")]
+ SqlxError(#[from] sqlx::Error),
+ #[error("entry not found")]
+ NotFound,
+}
+
+pub async fn select_combo_token_by_account(
+ pool: &PgPool,
+ account_uid: &str,
+) -> Result {
+ query_as("SELECT * from t_combo_token where account_uid = ($1)")
+ .bind(account_uid)
+ .fetch_optional(pool)
+ .await?
+ .ok_or(DbError::NotFound)
+}
+
+pub async fn select_player_uid_by_account(
+ pool: &PgPool,
+ account_uid: &str,
+) -> Result {
+ query_as("SELECT * from t_user_uid where account_uid = ($1)")
+ .bind(account_uid)
+ .fetch_optional(pool)
+ .await?
+ .ok_or(DbError::NotFound)
+}
+
+pub async fn insert_player_uid_by_account(
+ pool: &PgPool,
+ account_uid: &str,
+ platform: u32,
+) -> Result {
+ let ext = serde_json::to_string(&PlayerExtJsonData {
+ reg_platform: platform,
+ })
+ .unwrap();
+
+ Ok(
+ query_as("INSERT INTO t_user_uid (account_uid, ext) VALUES ($1, $2) RETURNING *")
+ .bind(account_uid)
+ .bind(ext)
+ .fetch_one(pool)
+ .await?,
+ )
+}
+
+pub async fn select_player_data_by_uid(
+ pool: &PgPool,
+ uid: i32,
+) -> Result {
+ query_as("SELECT * from t_player_data where uid = ($1)")
+ .bind(uid)
+ .fetch_optional(pool)
+ .await?
+ .ok_or(DbError::NotFound)
+}
+
+pub async fn insert_player_data_by_uid(
+ pool: &PgPool,
+ uid: i32,
+ bin_data: Vec,
+) -> Result<(), DbError> {
+ query("INSERT into t_player_data VALUES ($1, $2)")
+ .bind(uid)
+ .bind(bin_data)
+ .execute(pool)
+ .await?;
+
+ Ok(())
+}
+
+pub async fn update_player_data_by_uid(
+ pool: &PgPool,
+ uid: i32,
+ bin_data: Vec,
+) -> Result<(), DbError> {
+ query("UPDATE t_player_data SET bin_data = ($1) WHERE uid = ($2)")
+ .bind(bin_data)
+ .bind(uid)
+ .execute(pool)
+ .await?;
+
+ Ok(())
+}
diff --git a/nap_gameserver/src/handlers/abyss.rs b/nap_gameserver/src/handlers/abyss.rs
new file mode 100644
index 0000000..0bf5939
--- /dev/null
+++ b/nap_gameserver/src/handlers/abyss.rs
@@ -0,0 +1,25 @@
+use super::*;
+
+pub async fn on_get_abyss_info(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetAbyssInfoCsReq,
+) -> NetResult {
+ Ok(GetAbyssInfoScRsp {
+ retcode: Retcode::RetSucc.into(),
+ abyss_info: Some(AbyssInfo::default()),
+ abyss_group_list: Vec::new(),
+ ..Default::default()
+ })
+}
+
+pub async fn on_get_completed_abyss_group_list(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetCompletedAbyssGroupListCsReq,
+) -> NetResult {
+ Ok(GetCompletedAbyssGroupListScRsp {
+ retcode: Retcode::RetSucc.into(),
+ ..Default::default()
+ })
+}
diff --git a/nap_gameserver/src/handlers/activity.rs b/nap_gameserver/src/handlers/activity.rs
new file mode 100644
index 0000000..7ac4a8f
--- /dev/null
+++ b/nap_gameserver/src/handlers/activity.rs
@@ -0,0 +1,23 @@
+use super::*;
+
+pub async fn on_get_activity_data(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetActivityDataCsReq,
+) -> NetResult {
+ Ok(GetActivityDataScRsp {
+ retcode: Retcode::RetSucc.into(),
+ ..Default::default()
+ })
+}
+
+pub async fn on_get_web_activity_data(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetWebActivityDataCsReq,
+) -> NetResult {
+ Ok(GetWebActivityDataScRsp {
+ retcode: Retcode::RetSucc.into(),
+ ..Default::default()
+ })
+}
diff --git a/nap_gameserver/src/handlers/arcade.rs b/nap_gameserver/src/handlers/arcade.rs
new file mode 100644
index 0000000..2091bcb
--- /dev/null
+++ b/nap_gameserver/src/handlers/arcade.rs
@@ -0,0 +1,12 @@
+use super::*;
+
+pub async fn on_get_arcade_data(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetArcadeDataCsReq,
+) -> NetResult {
+ Ok(GetArcadeDataScRsp {
+ retcode: Retcode::RetSucc.into(),
+ ..Default::default()
+ })
+}
diff --git a/nap_gameserver/src/handlers/avatar.rs b/nap_gameserver/src/handlers/avatar.rs
new file mode 100644
index 0000000..bde7d13
--- /dev/null
+++ b/nap_gameserver/src/handlers/avatar.rs
@@ -0,0 +1,30 @@
+use crate::logic::role::Avatar;
+
+use super::*;
+
+pub async fn on_get_avatar_data(
+ _session: &NetSession,
+ player: &mut Player,
+ _req: GetAvatarDataCsReq,
+) -> NetResult {
+ Ok(GetAvatarDataScRsp {
+ retcode: Retcode::RetSucc.into(),
+ avatar_list: player
+ .role_model
+ .avatar_list
+ .iter()
+ .map(Avatar::to_client)
+ .collect(),
+ })
+}
+
+pub async fn on_get_buddy_data(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetBuddyDataCsReq,
+) -> NetResult {
+ Ok(GetBuddyDataScRsp {
+ retcode: Retcode::RetSucc.into(),
+ ..Default::default()
+ })
+}
diff --git a/nap_gameserver/src/handlers/battle_pass.rs b/nap_gameserver/src/handlers/battle_pass.rs
new file mode 100644
index 0000000..3f5e4c0
--- /dev/null
+++ b/nap_gameserver/src/handlers/battle_pass.rs
@@ -0,0 +1,12 @@
+use super::*;
+
+pub async fn on_get_battle_pass_data(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetBattlePassDataCsReq,
+) -> NetResult {
+ Ok(GetBattlePassDataScRsp {
+ retcode: Retcode::RetSucc.into(),
+ ..Default::default()
+ })
+}
diff --git a/nap_gameserver/src/handlers/cafe.rs b/nap_gameserver/src/handlers/cafe.rs
new file mode 100644
index 0000000..e51d130
--- /dev/null
+++ b/nap_gameserver/src/handlers/cafe.rs
@@ -0,0 +1,23 @@
+use super::*;
+
+pub async fn on_get_cafe_data(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetCafeDataCsReq,
+) -> NetResult {
+ Ok(GetCafeDataScRsp {
+ retcode: Retcode::RetSucc.into(),
+ cafe_data: Some(CafeData::default()),
+ })
+}
+
+pub async fn on_get_reward_buff_data(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetRewardBuffDataCsReq,
+) -> NetResult {
+ Ok(GetRewardBuffDataScRsp {
+ retcode: Retcode::RetSucc.into(),
+ info: Some(RewardBuffData::default()),
+ })
+}
diff --git a/nap_gameserver/src/handlers/character_quest.rs b/nap_gameserver/src/handlers/character_quest.rs
new file mode 100644
index 0000000..2b26418
--- /dev/null
+++ b/nap_gameserver/src/handlers/character_quest.rs
@@ -0,0 +1,23 @@
+use super::*;
+
+pub async fn on_get_character_quest_list(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetCharacterQuestListCsReq,
+) -> NetResult {
+ Ok(GetCharacterQuestListScRsp {
+ retcode: Retcode::RetSucc.into(),
+ ..Default::default()
+ })
+}
+
+pub async fn on_get_photo_wall_data(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetPhotoWallDataCsReq,
+) -> NetResult {
+ Ok(GetPhotoWallDataScRsp {
+ retcode: Retcode::RetSucc.into(),
+ ..Default::default()
+ })
+}
diff --git a/nap_gameserver/src/handlers/client_systems.rs b/nap_gameserver/src/handlers/client_systems.rs
new file mode 100644
index 0000000..900ea63
--- /dev/null
+++ b/nap_gameserver/src/handlers/client_systems.rs
@@ -0,0 +1,159 @@
+use crate::logic::{EOperator, ESystem};
+
+use super::*;
+
+use data::tables;
+
+pub async fn on_get_tips_info(
+ _session: &NetSession,
+ _player: &mut Player,
+ req: GetTipsInfoCsReq,
+) -> NetResult {
+ Ok(GetTipsInfoScRsp {
+ retcode: Retcode::RetSucc.into(),
+ tips_info: Some(TipsInfo::default()),
+ ofolagfmcmo: req.ofolagfmcmo, // tips group type
+ })
+}
+
+pub async fn on_get_client_systems_info(
+ _session: &NetSession,
+ player: &mut Player,
+ _req: GetClientSystemsInfoCsReq,
+) -> NetResult {
+ Ok(GetClientSystemsInfoScRsp {
+ retcode: Retcode::RetSucc.into(),
+ info: Some(ClientSystemsInfo {
+ post_girl_data: Some(PostGirlData {
+ selected_post_girl_id_list: tables::post_girl_config_template_tb::iter()
+ .map(|template| template.id)
+ .collect(),
+ post_girl_list: tables::post_girl_config_template_tb::iter()
+ .map(|template| PostGirlItem {
+ template_id: template.id,
+ unlock_time: 1000,
+ })
+ .collect(),
+ ..Default::default()
+ }),
+ unlock_data: Some(player.lock_model.to_client()),
+ hbhfjgbahgf: Some(Aboegnnepmi::default()),
+ ..Default::default()
+ }),
+ })
+}
+
+pub async fn on_get_news_stand_data(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetNewsStandDataCsReq,
+) -> NetResult {
+ Ok(GetNewsStandDataScRsp {
+ retcode: Retcode::RetSucc.into(),
+ news_stand_data: Some(NewsStandData::default()),
+ })
+}
+
+pub async fn on_get_trashbin_hermit_data(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetTrashbinHermitDataCsReq,
+) -> NetResult {
+ Ok(GetTrashbinHermitDataScRsp {
+ retcode: Retcode::RetSucc.into(),
+ trashbin_hermit_data: Some(TrashbinHermitData::default()),
+ })
+}
+
+pub async fn on_get_exploration_data(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetExplorationDataCsReq,
+) -> NetResult {
+ Ok(GetExplorationDataScRsp {
+ retcode: Retcode::RetSucc.into(),
+ ..Default::default()
+ })
+}
+
+pub async fn on_report_ui_layout_platform(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: ReportUiLayoutPlatformCsReq,
+) -> NetResult {
+ Ok(ReportUiLayoutPlatformScRsp {
+ retcode: Retcode::RetSucc.into(),
+ })
+}
+
+pub async fn on_unlock_newbie_group(
+ _session: &NetSession,
+ _player: &mut Player,
+ req: UnlockNewbieGroupCsReq,
+) -> NetResult {
+ Ok(UnlockNewbieGroupScRsp {
+ retcode: Retcode::RetSucc.into(),
+ group_id: req.group_id,
+ })
+}
+
+pub async fn on_battle_report(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: BattleReportCsReq,
+) -> NetResult {
+ Ok(BattleReportScRsp {
+ retcode: Retcode::RetSucc.into(),
+ })
+}
+
+pub async fn on_player_operation(
+ _session: &NetSession,
+ _player: &mut Player,
+ req: PlayerOperationCsReq,
+) -> NetResult {
+ tracing::info!(
+ "PlayerOperation(system={:?}, operator={:?}, param={})",
+ ESystem::from(req.system),
+ EOperator::from(req.operator),
+ req.param
+ );
+
+ Ok(PlayerOperationScRsp {
+ retcode: Retcode::RetSucc.into(),
+ })
+}
+
+pub async fn on_pop_up_window_seen(
+ _session: &NetSession,
+ _player: &mut Player,
+ req: PopUpWindowSeenCsReq,
+) -> NetResult {
+ Ok(PopUpWindowSeenScRsp {
+ retcode: Retcode::RetSucc.into(),
+ popup_group_id_list: req.popup_group_id_list,
+ })
+}
+
+pub async fn on_report_system_settings_change(
+ _session: &NetSession,
+ _player: &mut Player,
+ req: ReportSystemSettingsChangeCsReq,
+) -> NetResult {
+ tracing::info!("system settings change {req:?}");
+
+ Ok(ReportSystemSettingsChangeScRsp {
+ retcode: Retcode::RetSucc.into(),
+ })
+}
+
+pub async fn on_interact_with_scene_object(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: InteractWithSceneObjectCsReq,
+) -> NetResult {
+ // this request is used for interaction with STATIC scene objects (not controlled by server, e.g. door in workshop)
+ Ok(InteractWithSceneObjectScRsp {
+ retcode: Retcode::RetSucc.into(),
+ })
+}
diff --git a/nap_gameserver/src/handlers/collect.rs b/nap_gameserver/src/handlers/collect.rs
new file mode 100644
index 0000000..09e9d2d
--- /dev/null
+++ b/nap_gameserver/src/handlers/collect.rs
@@ -0,0 +1,34 @@
+use super::*;
+
+pub async fn on_get_collect_map(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetCollectMapCsReq,
+) -> NetResult {
+ Ok(GetCollectMapScRsp {
+ retcode: Retcode::RetSucc.into(),
+ collect_map: Some(CollectMap::default()),
+ })
+}
+
+pub async fn on_get_workbench_info(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetWorkbenchInfoCsReq,
+) -> NetResult {
+ Ok(GetWorkbenchInfoScRsp {
+ retcode: Retcode::RetSucc.into(),
+ workbench_info: Some(WorkbenchInfo::default()),
+ })
+}
+
+pub async fn on_get_abyss_reward_data(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetAbyssRewardDataCsReq,
+) -> NetResult {
+ Ok(GetAbyssRewardDataScRsp {
+ retcode: Retcode::RetSucc.into(),
+ abyss_reward_data: Some(AbyssRewardData::default()),
+ })
+}
diff --git a/nap_gameserver/src/handlers/core/error.rs b/nap_gameserver/src/handlers/core/error.rs
new file mode 100644
index 0000000..2d47cc2
--- /dev/null
+++ b/nap_gameserver/src/handlers/core/error.rs
@@ -0,0 +1,36 @@
+use proto::Retcode;
+use thiserror::Error;
+
+use crate::logic::game::LogicError;
+
+pub type NetResult = Result;
+
+#[derive(Error, Debug)]
+pub enum PacketHandlingError {
+ #[error("protobuf decode failed: {0}")]
+ DecodeFailed(#[from] prost::DecodeError),
+ #[error("I/O error: {0}")]
+ IoError(#[from] std::io::Error),
+ #[error("net error: {0}")]
+ Net(#[from] NetError),
+ #[error("soft logout performed")]
+ Logout,
+}
+
+#[derive(Error, Debug)]
+pub enum NetError {
+ #[error("I/O error: {0}")]
+ IoError(#[from] std::io::Error),
+ #[error("logic error: {0}")]
+ LogicError(#[from] LogicError),
+ #[error("retcode: {0:?}")]
+ ErrCode(Retcode),
+ #[error("soft logout performed")]
+ Logout,
+}
+
+impl From for NetError {
+ fn from(value: Retcode) -> Self {
+ Self::ErrCode(value)
+ }
+}
diff --git a/nap_gameserver/src/handlers/core/macros.rs b/nap_gameserver/src/handlers/core/macros.rs
new file mode 100644
index 0000000..2c75236
--- /dev/null
+++ b/nap_gameserver/src/handlers/core/macros.rs
@@ -0,0 +1,126 @@
+#[macro_export]
+macro_rules! auth_req_handlers {
+ ($($module:ident::$name:ident;)*) => {
+ pub async fn handle_auth_request(session: &crate::net::NetSession, packet: &crate::net::NetPacket, state: &crate::ServerState) -> Result {
+ use ::prost::Message;
+ use crate::handlers::core::NetError;
+ use crate::handlers::core::PacketHandlingError;
+ ::paste::paste! {
+ match packet.cmd_id {
+ $(
+ ::proto::[<$name CsReq>]::CMD_ID => {
+ let mut req = ::proto::[<$name CsReq>]::decode(&*packet.body)?;
+ req.xor_fields();
+
+ let rsp = match crate::handlers::$module::[](&session, &state.player_mgr, req).await {
+ Ok(rsp) => {
+ ::tracing::info!(concat!("[LOGIN] successfully handled request ", stringify!($name)));
+ rsp
+ },
+ Err(NetError::ErrCode(retcode)) => {
+ ::tracing::info!("[LOGIN] request {} was handled, retcode: {retcode:?}", stringify!($name));
+ [<$name ScRsp>] {
+ retcode: retcode.into(),
+ ..Default::default()
+ }
+ },
+ Err(err) => return Err(PacketHandlingError::Net(err)),
+ };
+
+ session.send_rsp(packet.head.packet_id, rsp).await?;
+ Ok(true)
+ }
+ )*
+ _ => Ok(false),
+ }
+ }
+ }
+ };
+}
+
+#[macro_export]
+macro_rules! req_handlers {
+ ($($module:ident::$name:ident;)*) => {
+ pub async fn handle_request(session: &crate::net::NetSession, packet: &crate::net::NetPacket, state: &crate::ServerState) -> Result {
+ use ::prost::Message;
+ use crate::handlers::core::NetError;
+ use crate::handlers::core::PacketHandlingError;
+ ::paste::paste! {
+ match packet.cmd_id {
+ $(
+ ::proto::[<$name CsReq>]::CMD_ID => {
+ let player_uid = *session.player_uid().unwrap(); // Should never be None here
+ let Some(player_lock) = state.player_mgr.get_player(player_uid).await else {
+ ::tracing::error!("PlayerManager::get_player returned None, uid={player_uid}");
+ return Ok(true);
+ };
+
+ let mut req = ::proto::[<$name CsReq>]::decode(&*packet.body)?;
+ req.xor_fields();
+
+ let rsp = match crate::handlers::$module::[](&session, &mut *player_lock.lock().await, req).await {
+ Ok(rsp) => {
+ ::tracing::info!(concat!("successfully handled request ", stringify!($name)));
+ rsp
+ }
+ Err(NetError::ErrCode(retcode)) => {
+ ::tracing::info!("request {} was handled, retcode: {retcode:?}", stringify!($name));
+ [<$name ScRsp>] {
+ retcode: retcode.into(),
+ ..Default::default()
+ }
+ },
+ Err(err) => return Err(PacketHandlingError::Net(err)),
+ };
+
+ session.send_rsp(packet.head.packet_id, rsp).await?;
+ Ok(true)
+ }
+ )*
+ _ => Ok(false),
+ }
+ }
+ }
+ };
+}
+
+#[macro_export]
+macro_rules! notify_handlers {
+ ($($module:ident::$name:ident;)*) => {
+ pub async fn handle_notify(session: &crate::net::NetSession, packet: &crate::net::NetPacket, state: &crate::ServerState) -> Result {
+ use ::prost::Message;
+ use crate::handlers::core::NetError;
+ use crate::handlers::core::PacketHandlingError;
+ ::paste::paste! {
+ match packet.cmd_id {
+ $(
+ ::proto::[<$name Notify>]::CMD_ID => {
+ let player_uid = *session.player_uid().unwrap(); // Should never be None here
+ let Some(player_lock) = state.player_mgr.get_player(player_uid).await else {
+ ::tracing::error!("PlayerManager::get_player returned None, uid={player_uid}");
+ return Ok(true);
+ };
+
+ let mut ntf = ::proto::[<$name Notify>]::decode(&*packet.body)?;
+ ntf.xor_fields();
+
+ match crate::handlers::$module::[](session, &mut *player_lock.lock().await, ntf).await {
+ Ok(()) => (),
+ Err(NetError::Logout) => return Err(PacketHandlingError::Logout),
+ Err(err) => return Err(PacketHandlingError::Net(err)),
+ }
+
+ ::tracing::info!("successfully handled notify {}", stringify!($name));
+ Ok(true)
+ }
+ )*
+ _ => Ok(false),
+ }
+ }
+ }
+ };
+}
+
+pub use auth_req_handlers;
+pub use notify_handlers;
+pub use req_handlers;
diff --git a/nap_gameserver/src/handlers/core/mod.rs b/nap_gameserver/src/handlers/core/mod.rs
new file mode 100644
index 0000000..6d022f9
--- /dev/null
+++ b/nap_gameserver/src/handlers/core/mod.rs
@@ -0,0 +1,5 @@
+mod error;
+mod macros;
+
+pub use error::{NetError, NetResult, PacketHandlingError};
+pub use macros::{auth_req_handlers, notify_handlers, req_handlers};
diff --git a/nap_gameserver/src/handlers/daily_challenge.rs b/nap_gameserver/src/handlers/daily_challenge.rs
new file mode 100644
index 0000000..9822685
--- /dev/null
+++ b/nap_gameserver/src/handlers/daily_challenge.rs
@@ -0,0 +1,12 @@
+use super::*;
+
+pub async fn on_get_daily_challenge_info(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetDailyChallengeInfoCsReq,
+) -> NetResult {
+ Ok(GetDailyChallengeInfoScRsp {
+ retcode: Retcode::RetSucc.into(),
+ info: Some(DailyChallengeInfo::default()),
+ })
+}
diff --git a/nap_gameserver/src/handlers/embattles.rs b/nap_gameserver/src/handlers/embattles.rs
new file mode 100644
index 0000000..260900e
--- /dev/null
+++ b/nap_gameserver/src/handlers/embattles.rs
@@ -0,0 +1,23 @@
+use super::*;
+
+pub async fn on_get_embattles_data(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetEmbattlesDataCsReq,
+) -> NetResult {
+ Ok(GetEmbattlesDataScRsp {
+ embattles_data: Some(EmbattlesData::default()),
+ retcode: Retcode::RetSucc.into(),
+ })
+}
+
+pub async fn on_report_battle_team(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: ReportBattleTeamCsReq,
+) -> NetResult {
+ Ok(ReportBattleTeamScRsp {
+ retcode: Retcode::RetSucc.into(),
+ ..Default::default()
+ })
+}
diff --git a/nap_gameserver/src/handlers/fairy.rs b/nap_gameserver/src/handlers/fairy.rs
new file mode 100644
index 0000000..f29c310
--- /dev/null
+++ b/nap_gameserver/src/handlers/fairy.rs
@@ -0,0 +1,12 @@
+use super::*;
+
+pub async fn on_get_fairy_info(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetFairyInfoCsReq,
+) -> NetResult {
+ Ok(GetFairyInfoScRsp {
+ retcode: Retcode::RetSucc.into(),
+ info: Some(FairyInfo::default()),
+ })
+}
diff --git a/nap_gameserver/src/handlers/friend.rs b/nap_gameserver/src/handlers/friend.rs
new file mode 100644
index 0000000..850e49d
--- /dev/null
+++ b/nap_gameserver/src/handlers/friend.rs
@@ -0,0 +1,25 @@
+use super::*;
+
+pub async fn on_get_friend_list(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetFriendListCsReq,
+) -> NetResult {
+ Ok(GetFriendListScRsp {
+ retcode: Retcode::RetSucc.into(),
+ ..Default::default()
+ })
+}
+
+pub async fn on_get_friend_limit_info(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetFriendLimitInfoCsReq,
+) -> NetResult {
+ Ok(GetFriendLimitInfoScRsp {
+ retcode: Retcode::RetSucc.into(),
+ ngaiiafngbk: 30,
+ ajndiihdlfa: 300,
+ ..Default::default()
+ })
+}
diff --git a/nap_gameserver/src/handlers/gacha.rs b/nap_gameserver/src/handlers/gacha.rs
new file mode 100644
index 0000000..3b1637e
--- /dev/null
+++ b/nap_gameserver/src/handlers/gacha.rs
@@ -0,0 +1,13 @@
+use super::*;
+
+pub async fn on_get_gacha_data(
+ _session: &NetSession,
+ _player: &mut Player,
+ req: GetGachaDataCsReq,
+) -> NetResult {
+ Ok(GetGachaDataScRsp {
+ retcode: Retcode::RetSucc.into(),
+ gacha_type: req.gacha_type,
+ gacha_data: Some(GachaData::default()),
+ })
+}
diff --git a/nap_gameserver/src/handlers/hadal_zone.rs b/nap_gameserver/src/handlers/hadal_zone.rs
new file mode 100644
index 0000000..b8b8b26
--- /dev/null
+++ b/nap_gameserver/src/handlers/hadal_zone.rs
@@ -0,0 +1,12 @@
+use super::*;
+
+pub async fn on_get_hadal_zone_data(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetHadalZoneDataCsReq,
+) -> NetResult {
+ Ok(GetHadalZoneDataScRsp {
+ retcode: Retcode::RetSucc.into(),
+ ..Default::default()
+ })
+}
diff --git a/nap_gameserver/src/handlers/item.rs b/nap_gameserver/src/handlers/item.rs
new file mode 100644
index 0000000..d68246e
--- /dev/null
+++ b/nap_gameserver/src/handlers/item.rs
@@ -0,0 +1,15 @@
+use super::*;
+
+pub async fn on_get_item_data(
+ _session: &NetSession,
+ player: &mut Player,
+ _req: GetItemDataCsReq,
+) -> NetResult {
+ let item_model = &player.item_model;
+
+ Ok(GetItemDataScRsp {
+ retcode: Retcode::RetSucc.into(),
+ resource_list: item_model.resources.iter().map(|i| i.to_client()).collect(),
+ ..Default::default()
+ })
+}
diff --git a/nap_gameserver/src/handlers/login.rs b/nap_gameserver/src/handlers/login.rs
new file mode 100644
index 0000000..91e510b
--- /dev/null
+++ b/nap_gameserver/src/handlers/login.rs
@@ -0,0 +1,59 @@
+use common::cryptography::{rsa_decrypt, rsa_encrypt, rsa_sign};
+use rand::RngCore;
+
+use crate::{logic::player::PlayerManager, net::NetSessionState};
+
+use super::*;
+
+pub async fn on_player_get_token(
+ session: &NetSession,
+ player_mgr: &PlayerManager,
+ req: PlayerGetTokenCsReq,
+) -> NetResult {
+ session.set_state(NetSessionState::PlayerGetTokenCsReq);
+
+ let uid = player_mgr
+ .authorize(&req.account_uid, &req.token, req.platform_type)
+ .await?;
+
+ let client_rand_key = rbase64::decode(&req.client_rand_key).map_err(|_| Retcode::RetFail)?;
+ let client_rand_key = u64::from_le_bytes(rsa_decrypt(&client_rand_key).try_into().unwrap());
+ let server_rand_key = rand::thread_rng().next_u64();
+
+ session.set_session_key(client_rand_key ^ server_rand_key);
+ session.set_account_uid(req.account_uid);
+ session.set_player_uid(uid);
+ session.set_state(NetSessionState::PlayerGetTokenScRsp);
+
+ Ok(PlayerGetTokenScRsp {
+ retcode: Retcode::RetSucc.into(),
+ uid,
+ server_rand_key: rbase64::encode(&rsa_encrypt(&server_rand_key.to_le_bytes())),
+ sign: rbase64::encode(&rsa_sign(&server_rand_key.to_le_bytes())),
+ ..Default::default()
+ })
+}
+
+pub async fn on_player_login(
+ session: &NetSession,
+ player_mgr: &PlayerManager,
+ _req: PlayerLoginCsReq,
+) -> NetResult {
+ session.set_state(NetSessionState::PlayerLoginCsReq);
+
+ let player_uid = *session.player_uid().ok_or(Retcode::RetFail)?;
+ let player_lock = player_mgr
+ .get_player(player_uid)
+ .await
+ .ok_or(Retcode::RetFail)?;
+
+ let mut player = player_lock.lock().await;
+ player.set_current_session(session.id());
+ player.on_login();
+
+ session.set_state(NetSessionState::StartBasicsReq);
+ Ok(PlayerLoginScRsp {
+ retcode: Retcode::RetSucc.into(),
+ ..Default::default()
+ })
+}
diff --git a/nap_gameserver/src/handlers/mail.rs b/nap_gameserver/src/handlers/mail.rs
new file mode 100644
index 0000000..f442344
--- /dev/null
+++ b/nap_gameserver/src/handlers/mail.rs
@@ -0,0 +1,12 @@
+use super::*;
+
+pub async fn on_get_player_mails(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetPlayerMailsCsReq,
+) -> NetResult {
+ Ok(GetPlayerMailsScRsp {
+ retcode: Retcode::RetSucc.into(),
+ ..Default::default()
+ })
+}
diff --git a/nap_gameserver/src/handlers/main_city_revival.rs b/nap_gameserver/src/handlers/main_city_revival.rs
new file mode 100644
index 0000000..494fac8
--- /dev/null
+++ b/nap_gameserver/src/handlers/main_city_revival.rs
@@ -0,0 +1,12 @@
+use super::*;
+
+pub async fn on_get_main_city_revival_data(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetMainCityRevivalDataCsReq,
+) -> NetResult {
+ Ok(GetMainCityRevivalDataScRsp {
+ retcode: Retcode::RetSucc.into(),
+ main_city_revival: Some(MainCityRevivalData::default()),
+ })
+}
diff --git a/nap_gameserver/src/handlers/misc.rs b/nap_gameserver/src/handlers/misc.rs
new file mode 100644
index 0000000..11e73e0
--- /dev/null
+++ b/nap_gameserver/src/handlers/misc.rs
@@ -0,0 +1,34 @@
+use common::util;
+
+use super::*;
+
+pub async fn on_get_server_timestamp(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetServerTimestampCsReq,
+) -> NetResult {
+ Ok(GetServerTimestampScRsp {
+ retcode: Retcode::RetSucc.into(),
+ timestamp: util::cur_timestamp_ms(),
+ utc_offset: 3,
+ })
+}
+
+pub async fn on_get_authkey(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetAuthkeyCsReq,
+) -> NetResult {
+ Ok(GetAuthkeyScRsp::default())
+}
+
+pub async fn on_get_cut_scene_key_info(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetCutSceneKeyInfoCsReq,
+) -> NetResult {
+ Ok(GetCutSceneKeyInfoScRsp {
+ key_map: data::usm_key_map().clone(),
+ retcode: Retcode::RetSucc.into(),
+ })
+}
diff --git a/nap_gameserver/src/handlers/mod.rs b/nap_gameserver/src/handlers/mod.rs
new file mode 100644
index 0000000..273923d
--- /dev/null
+++ b/nap_gameserver/src/handlers/mod.rs
@@ -0,0 +1,117 @@
+mod abyss;
+mod activity;
+mod arcade;
+mod avatar;
+mod battle_pass;
+mod cafe;
+mod character_quest;
+mod client_systems;
+mod collect;
+mod daily_challenge;
+mod embattles;
+mod fairy;
+mod friend;
+mod gacha;
+mod hadal_zone;
+mod item;
+mod login;
+mod mail;
+mod main_city_revival;
+mod misc;
+mod month_card;
+mod perform;
+mod player;
+mod private_message;
+mod quest;
+mod ramen;
+mod vhs_store;
+mod world;
+
+mod core;
+
+use crate::logic::Player;
+use core::NetResult;
+use core::{auth_req_handlers, notify_handlers, req_handlers};
+
+pub use core::PacketHandlingError;
+
+use crate::net::NetSession;
+use proto::*;
+
+auth_req_handlers! {
+ login::PlayerGetToken;
+ login::PlayerLogin;
+}
+
+req_handlers! {
+ player::GetPlayerBasicInfo;
+ player::CreateRole;
+ player::GetPlayerTransaction;
+ item::GetItemData;
+ avatar::GetAvatarData;
+ avatar::GetBuddyData;
+ quest::GetQuestData;
+ quest::GetYorozuyaInfo;
+ quest::GetArchiveInfo;
+ abyss::GetAbyssInfo;
+ gacha::GetGachaData;
+ ramen::GetRamenData;
+ cafe::GetCafeData;
+ cafe::GetRewardBuffData;
+ mail::GetPlayerMails;
+ fairy::GetFairyInfo;
+ client_systems::GetTipsInfo;
+ client_systems::GetClientSystemsInfo;
+ private_message::GetPrivateMessageData;
+ collect::GetCollectMap;
+ collect::GetWorkbenchInfo;
+ collect::GetAbyssRewardData;
+ vhs_store::GetVhsStoreInfo;
+ activity::GetActivityData;
+ activity::GetWebActivityData;
+ embattles::GetEmbattlesData;
+ client_systems::GetNewsStandData;
+ client_systems::GetTrashbinHermitData;
+ client_systems::GetExplorationData;
+ main_city_revival::GetMainCityRevivalData;
+ arcade::GetArcadeData;
+ battle_pass::GetBattlePassData;
+ hadal_zone::GetHadalZoneData;
+ daily_challenge::GetDailyChallengeInfo;
+ abyss::GetCompletedAbyssGroupList;
+ friend::GetFriendList;
+ friend::GetFriendLimitInfo;
+ character_quest::GetCharacterQuestList;
+ character_quest::GetPhotoWallData;
+ month_card::GetMonthCardDayReward;
+ world::EnterWorld;
+ world::EnterSection;
+ world::SavePosInMainCity;
+ world::WorldInitFinish;
+ world::AdvanceBeginnerProcedure;
+ world::BeginnerBattleBegin;
+ world::BeginnerBattleEnd;
+ world::BeginnerBattleRebegin;
+ world::StartTrialFightingMission;
+ world::EndBattle;
+ world::LeaveCurDungeon;
+ client_systems::ReportUiLayoutPlatform;
+ client_systems::PlayerOperation;
+ client_systems::UnlockNewbieGroup;
+ client_systems::BattleReport;
+ client_systems::PopUpWindowSeen;
+ client_systems::ReportSystemSettingsChange;
+ client_systems::InteractWithSceneObject;
+ perform::PerformTrigger;
+ perform::PerformEnd;
+ perform::PerformJump;
+ misc::GetAuthkey;
+ misc::GetServerTimestamp;
+ misc::GetCutSceneKeyInfo;
+ embattles::ReportBattleTeam;
+}
+
+notify_handlers! {
+ player::KeepAlive;
+ player::PlayerLogout;
+}
diff --git a/nap_gameserver/src/handlers/month_card.rs b/nap_gameserver/src/handlers/month_card.rs
new file mode 100644
index 0000000..29b0e46
--- /dev/null
+++ b/nap_gameserver/src/handlers/month_card.rs
@@ -0,0 +1,12 @@
+use super::*;
+
+pub async fn on_get_month_card_day_reward(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetMonthCardDayRewardCsReq,
+) -> NetResult {
+ Ok(GetMonthCardDayRewardScRsp {
+ retcode: Retcode::RetSucc.into(),
+ ..Default::default()
+ })
+}
diff --git a/nap_gameserver/src/handlers/perform.rs b/nap_gameserver/src/handlers/perform.rs
new file mode 100644
index 0000000..0842d0b
--- /dev/null
+++ b/nap_gameserver/src/handlers/perform.rs
@@ -0,0 +1,57 @@
+use super::core::NetError;
+
+use crate::logic::{
+ game::{GameInstance, LogicError},
+ procedure::ProcedureAction,
+};
+
+use super::*;
+
+pub async fn on_perform_trigger(
+ _session: &NetSession,
+ player: &mut Player,
+ req: PerformTriggerCsReq,
+) -> NetResult {
+ let GameInstance::Fresh(fresh_game) = &mut player.game_instance else {
+ return Err(NetError::from(Retcode::RetFail));
+ };
+
+ fresh_game
+ .procedure_mgr
+ .on_action(ProcedureAction::PerformTrigger)
+ .map_err(LogicError::from)?;
+
+ Ok(PerformTriggerScRsp {
+ retcode: Retcode::RetSucc.into(),
+ perform_uid: ((req.perform_type as i64) << 32) | req.perform_id as i64,
+ })
+}
+
+pub async fn on_perform_end(
+ _session: &NetSession,
+ player: &mut Player,
+ _req: PerformEndCsReq,
+) -> NetResult {
+ let GameInstance::Fresh(fresh_game) = &mut player.game_instance else {
+ return Err(NetError::from(Retcode::RetFail));
+ };
+
+ fresh_game
+ .procedure_mgr
+ .on_action(ProcedureAction::PerformEnd)
+ .map_err(LogicError::from)?;
+
+ Ok(PerformEndScRsp {
+ retcode: Retcode::RetSucc.into(),
+ })
+}
+
+pub async fn on_perform_jump(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: PerformJumpCsReq,
+) -> NetResult {
+ Ok(PerformJumpScRsp {
+ retcode: Retcode::RetSucc.into(),
+ })
+}
diff --git a/nap_gameserver/src/handlers/player.rs b/nap_gameserver/src/handlers/player.rs
new file mode 100644
index 0000000..1431beb
--- /dev/null
+++ b/nap_gameserver/src/handlers/player.rs
@@ -0,0 +1,75 @@
+use crate::logic::game::{GameInstance, LogicError};
+use crate::logic::procedure::ProcedureAction;
+
+use super::core::NetError;
+use super::*;
+
+pub async fn on_get_player_basic_info(
+ _session: &NetSession,
+ player: &mut Player,
+ _req: GetPlayerBasicInfoCsReq,
+) -> NetResult {
+ Ok(GetPlayerBasicInfoScRsp {
+ retcode: Retcode::RetSucc.into(),
+ basic_info: Some(player.basic_data_model.player_basic_info()),
+ })
+}
+
+pub async fn on_create_role(
+ session: &NetSession,
+ player: &mut Player,
+ req: CreateRoleCsReq,
+) -> NetResult {
+ let GameInstance::Fresh(fresh_game) = &mut player.game_instance else {
+ return Err(NetError::from(Retcode::RetFail));
+ };
+
+ fresh_game
+ .procedure_mgr
+ .on_action(ProcedureAction::SelectRole)
+ .map_err(LogicError::from)?;
+
+ player.set_frontend_avatar(req.avatar_id as i32)?;
+
+ session
+ .notify(PlayerSyncScNotify {
+ basic_info: Some(player.basic_data_model.player_basic_info()),
+ ..Default::default()
+ })
+ .await?;
+
+ Ok(CreateRoleScRsp {
+ retcode: Retcode::RetSucc.into(),
+ })
+}
+
+pub async fn on_get_player_transaction(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetPlayerTransactionCsReq,
+) -> NetResult {
+ Ok(GetPlayerTransactionScRsp {
+ retcode: Retcode::RetSucc.into(),
+ transaction: format!("{}-{}", 1337, 100),
+ })
+}
+
+pub async fn on_keep_alive(
+ _session: &NetSession,
+ _player: &mut Player,
+ _ntf: KeepAliveNotify,
+) -> NetResult<()> {
+ Ok(())
+}
+
+pub async fn on_player_logout(
+ session: &NetSession,
+ _player: &mut Player,
+ _ntf: PlayerLogoutNotify,
+) -> NetResult<()> {
+ tracing::info!(
+ "player logout requested (uid: {})",
+ session.player_uid().unwrap()
+ );
+ Err(NetError::Logout)
+}
diff --git a/nap_gameserver/src/handlers/private_message.rs b/nap_gameserver/src/handlers/private_message.rs
new file mode 100644
index 0000000..f56cb26
--- /dev/null
+++ b/nap_gameserver/src/handlers/private_message.rs
@@ -0,0 +1,12 @@
+use super::*;
+
+pub async fn on_get_private_message_data(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetPrivateMessageDataCsReq,
+) -> NetResult {
+ Ok(GetPrivateMessageDataScRsp {
+ retcode: Retcode::RetSucc.into(),
+ private_message_data: Some(PrivateMessageData::default()),
+ })
+}
diff --git a/nap_gameserver/src/handlers/quest.rs b/nap_gameserver/src/handlers/quest.rs
new file mode 100644
index 0000000..b48e5ca
--- /dev/null
+++ b/nap_gameserver/src/handlers/quest.rs
@@ -0,0 +1,35 @@
+use super::*;
+
+pub async fn on_get_quest_data(
+ _session: &NetSession,
+ _player: &mut Player,
+ req: GetQuestDataCsReq,
+) -> NetResult {
+ Ok(GetQuestDataScRsp {
+ retcode: Retcode::RetSucc.into(),
+ quest_type: req.quest_type,
+ quest_data: Some(QuestData::default()),
+ })
+}
+
+pub async fn on_get_yorozuya_info(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetYorozuyaInfoCsReq,
+) -> NetResult {
+ Ok(GetYorozuyaInfoScRsp {
+ retcode: Retcode::RetSucc.into(),
+ yorozuya_info: Some(YorozuyaInfo::default()),
+ })
+}
+
+pub async fn on_get_archive_info(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetArchiveInfoCsReq,
+) -> NetResult {
+ Ok(GetArchiveInfoScRsp {
+ retcode: Retcode::RetSucc.into(),
+ archive_info: Some(ArchiveInfo::default()),
+ })
+}
diff --git a/nap_gameserver/src/handlers/ramen.rs b/nap_gameserver/src/handlers/ramen.rs
new file mode 100644
index 0000000..5e58426
--- /dev/null
+++ b/nap_gameserver/src/handlers/ramen.rs
@@ -0,0 +1,12 @@
+use super::*;
+
+pub async fn on_get_ramen_data(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetRamenDataCsReq,
+) -> NetResult {
+ Ok(GetRamenDataScRsp {
+ retcode: Retcode::RetSucc.into(),
+ ramen_data: Some(RamenData::default()),
+ })
+}
diff --git a/nap_gameserver/src/handlers/vhs_store.rs b/nap_gameserver/src/handlers/vhs_store.rs
new file mode 100644
index 0000000..b83602f
--- /dev/null
+++ b/nap_gameserver/src/handlers/vhs_store.rs
@@ -0,0 +1,12 @@
+use super::*;
+
+pub async fn on_get_vhs_store_info(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: GetVhsStoreInfoCsReq,
+) -> NetResult {
+ Ok(GetVhsStoreInfoScRsp {
+ retcode: Retcode::RetSucc.into(),
+ info: Some(VhsStoreInfo::default()),
+ })
+}
diff --git a/nap_gameserver/src/handlers/world.rs b/nap_gameserver/src/handlers/world.rs
new file mode 100644
index 0000000..5822de4
--- /dev/null
+++ b/nap_gameserver/src/handlers/world.rs
@@ -0,0 +1,200 @@
+use super::core::NetError;
+
+use crate::{
+ logic::{game::*, procedure::ProcedureAction, ELocalPlayType},
+ net::NetSessionState,
+};
+
+use super::*;
+
+pub async fn on_enter_world(
+ session: &NetSession,
+ player: &mut Player,
+ _req: EnterWorldCsReq,
+) -> NetResult {
+ session.set_state(NetSessionState::EndBasicsReq);
+
+ if player.basic_data_model.beginner_procedure_id != -1 {
+ player.game_instance = GameInstance::Fresh(FreshGame::new(
+ player.basic_data_model.beginner_procedure_id,
+ ))
+ } else {
+ player.init_frontend_game()?;
+ }
+
+ let world_init_notify = player.game_instance.create_world_init_notify()?;
+ session.notify(world_init_notify).await?;
+
+ session.set_state(NetSessionState::EnterWorldScRsp);
+ Ok(EnterWorldScRsp {
+ retcode: Retcode::RetSucc.into(),
+ })
+}
+
+pub async fn on_advance_beginner_procedure(
+ session: &NetSession,
+ player: &mut Player,
+ req: AdvanceBeginnerProcedureCsReq,
+) -> NetResult {
+ let is_end = {
+ let GameInstance::Fresh(fresh_game) = &mut player.game_instance else {
+ return Err(NetError::from(Retcode::RetFail));
+ };
+
+ fresh_game
+ .procedure_mgr
+ .try_complete_procedure(req.procedure_id)
+ .map_err(LogicError::from)?;
+
+ player.basic_data_model.beginner_procedure_id = fresh_game.procedure_mgr.procedure_id();
+ fresh_game.procedure_mgr.is_end()
+ };
+
+ if is_end {
+ player.init_frontend_game()?;
+
+ let world_init_notify = player.game_instance.create_world_init_notify()?;
+ session.notify(world_init_notify).await?;
+ }
+
+ Ok(AdvanceBeginnerProcedureScRsp {
+ retcode: Retcode::RetSucc.into(),
+ next_procedure_id: req.procedure_id,
+ })
+}
+
+pub async fn on_beginner_battle_begin(
+ _session: &NetSession,
+ player: &mut Player,
+ req: BeginnerBattleBeginCsReq,
+) -> NetResult {
+ let GameInstance::Fresh(fresh_game) = &mut player.game_instance else {
+ return Err(NetError::from(Retcode::RetFail));
+ };
+
+ fresh_game
+ .procedure_mgr
+ .on_action(ProcedureAction::BeginnerBattleBegin)
+ .map_err(LogicError::from)?;
+
+ Ok(BeginnerBattleBeginScRsp {
+ retcode: Retcode::RetSucc.into(),
+ battle_uid: req.battle_id as i64,
+ })
+}
+
+pub async fn on_beginner_battle_end(
+ _session: &NetSession,
+ player: &mut Player,
+ req: BeginnerBattleEndCsReq,
+) -> NetResult {
+ let GameInstance::Fresh(fresh_game) = &mut player.game_instance else {
+ return Err(NetError::from(Retcode::RetFail));
+ };
+
+ tracing::info!(
+ "beginner battle end, id: {}, uid: {}, statistics: {:?}",
+ req.battle_id,
+ req.battle_uid,
+ req.battle_statistics
+ );
+
+ fresh_game
+ .procedure_mgr
+ .on_action(ProcedureAction::BeginnerBattleEnd)
+ .map_err(LogicError::from)?;
+
+ Ok(BeginnerBattleEndScRsp {
+ retcode: Retcode::RetSucc.into(),
+ })
+}
+
+pub async fn on_beginner_battle_rebegin(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: BeginnerBattleRebeginCsReq,
+) -> NetResult {
+ Ok(BeginnerBattleRebeginScRsp {
+ retcode: Retcode::RetSucc.into(),
+ })
+}
+
+pub async fn on_enter_section(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: EnterSectionCsReq,
+) -> NetResult {
+ Ok(EnterSectionScRsp {
+ retcode: Retcode::RetSucc.into(),
+ })
+}
+
+pub async fn on_save_pos_in_main_city(
+ _session: &NetSession,
+ player: &mut Player,
+ req: SavePosInMainCityCsReq,
+) -> NetResult {
+ if let Some(transform) = req.position {
+ player
+ .main_city_model
+ .update_position(transform.position, transform.rotation);
+ }
+
+ Ok(SavePosInMainCityScRsp {
+ retcode: Retcode::RetSucc.into(),
+ })
+}
+
+pub async fn on_world_init_finish(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: WorldInitFinishCsReq,
+) -> NetResult {
+ Ok(WorldInitFinishScRsp {
+ retcode: Retcode::RetSucc.into(),
+ })
+}
+
+pub async fn on_start_trial_fighting_mission(
+ session: &NetSession,
+ player: &mut Player,
+ req: StartTrialFightingMissionCsReq,
+) -> NetResult {
+ player.game_instance = GameInstance::Hollow(
+ HollowGame::create_training_game(req.quest_id, ELocalPlayType::TrainingRoomFight)
+ .map_err(LogicError::from)?,
+ );
+
+ let world_init_notify = player.game_instance.create_world_init_notify()?;
+ session.notify(world_init_notify).await?;
+
+ Ok(StartTrialFightingMissionScRsp {
+ retcode: Retcode::RetSucc.into(),
+ })
+}
+
+pub async fn on_end_battle(
+ _session: &NetSession,
+ _player: &mut Player,
+ _req: EndBattleCsReq,
+) -> NetResult {
+ Ok(EndBattleScRsp {
+ battle_reward: Some(BattleRewardInfo::default()),
+ retcode: Retcode::RetSucc.into(),
+ })
+}
+
+pub async fn on_leave_cur_dungeon(
+ session: &NetSession,
+ player: &mut Player,
+ _req: LeaveCurDungeonCsReq,
+) -> NetResult {
+ player.init_frontend_game()?;
+
+ let world_init_notify = player.game_instance.create_world_init_notify()?;
+ session.notify(world_init_notify).await?;
+
+ Ok(LeaveCurDungeonScRsp {
+ retcode: Retcode::RetSucc.into(),
+ })
+}
diff --git a/nap_gameserver/src/logic/enums.rs b/nap_gameserver/src/logic/enums.rs
new file mode 100644
index 0000000..6232c81
--- /dev/null
+++ b/nap_gameserver/src/logic/enums.rs
@@ -0,0 +1,144 @@
+use std::fmt::Display;
+
+use num_enum::FromPrimitive;
+
+#[derive(Debug, PartialEq, Eq, Clone, Copy, FromPrimitive)]
+#[repr(u32)]
+pub enum ESceneType {
+ #[default]
+ Unknown = 0,
+ Hall = 1,
+ Hollow = 2,
+ Fight = 3,
+ Fresh = 4,
+ MultiFight = 5,
+}
+
+#[derive(Debug, Default, PartialEq, Eq, Clone, Copy, FromPrimitive)]
+#[repr(u32)]
+pub enum ESystem {
+ #[default]
+ None = 0xFFFFFFFF,
+ VhsStore = 7,
+ Gacha = 21,
+ Hadal = 43,
+ MonsterCard = 40,
+ AbyssCollect = 45,
+ Vhs = 1,
+ ActivityPv = 48,
+ StoryModeSwitch = 12,
+ RamenStore = 8,
+ QteSwitch = 13,
+ DoubleElite = 36,
+ LandRevive = 35,
+ HadalShop = 47,
+ Role = 2,
+ Grocery = 10,
+ AvatarBase = 33,
+ Activity = 27,
+ BuddyInstall = 26,
+ AvatarEquip = 34,
+ TartarusHounds = 20,
+ BossBig = 38,
+ Buddy = 25,
+ Interknot = 6,
+ Workbench = 9,
+ HIA = 39,
+ Smithy = 3,
+ Trash = 23,
+ UseStoryMode = 15,
+ Photowall = 44,
+ AbyssShop = 46,
+ AbyssHeat = 29,
+ DailyQuest = 41,
+ Newsstand = 17,
+ Cafe = 22,
+ Rally = 42,
+ HollowQuest = 0,
+ Package = 4,
+ VideoShop = 11,
+ BattleDaily = 24,
+ Arcade = 19,
+ BossSmall = 37,
+ LineupSelect = 14,
+ ArcadeRoom = 30,
+ Teleport = 5,
+ Train = 32,
+ UseManualQteMode = 16,
+ ArcadeGame = 31,
+ Abyss = 28,
+ Toy = 18,
+}
+
+#[derive(Default, Debug, Clone, Copy, FromPrimitive)]
+#[repr(u32)]
+pub enum EOperator {
+ Enter = 0,
+ Log = 1,
+ Leave = 2,
+ #[default]
+ Undefined = 0xFFFFFFFF,
+}
+
+#[derive(Debug, Clone, Copy)]
+#[repr(u32)]
+pub enum TimePeriodType {
+ Morning = 0,
+ Evening = 1,
+ Night = 2,
+}
+
+impl Display for TimePeriodType {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ std::fmt::Debug::fmt(self, f)
+ }
+}
+
+#[derive(Default, Debug, Clone, Copy)]
+#[repr(u32)]
+pub enum WeatherType {
+ SunShine = 0,
+ Fog = 1,
+ Cloudy = 2,
+ Rain = 3,
+ Thunder = 4,
+ ThickFog = 5,
+ ThickCloudy = 6,
+ #[default]
+ None = 0xFFFFFFFF,
+}
+
+impl Display for WeatherType {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ std::fmt::Debug::fmt(self, f)
+ }
+}
+
+#[derive(Default, Debug, Clone, Copy)]
+pub enum ELocalPlayType {
+ TrainingRoom = 290,
+ BigBossBattle = 211,
+ BossLittleBattleLongfight = 215,
+ PureHollowBattle = 280,
+ DualElite = 208,
+ PureHollowBattleHardmode = 282,
+ OperationBetaDemo = 216,
+ AvatarDemoTrial = 213,
+ BossRushBattle = 218,
+ BossBattle = 210,
+ GuideSpecial = 203,
+ DailyChallenge = 206,
+ OperationTeamCoop = 219,
+ TrainingRoomFight = 291,
+ LevelZero = 205,
+ ArchiveLongFight = 212,
+ MpBigBossBattle = 214,
+ RallyLongFight = 207,
+ BigBossBattleLongfight = 217,
+ ArchiveBattle = 201,
+ PureHollowBattleLonghfight = 281,
+ HadalZone = 209,
+ ChessBoardBattle = 202,
+ #[default]
+ Unknown = 0,
+}
diff --git a/nap_gameserver/src/logic/game/fresh.rs b/nap_gameserver/src/logic/game/fresh.rs
new file mode 100644
index 0000000..6e45310
--- /dev/null
+++ b/nap_gameserver/src/logic/game/fresh.rs
@@ -0,0 +1,37 @@
+use proto::{DungeonInfo, FreshSceneInfo, SceneInfo};
+
+use crate::logic::{procedure::ProcedureManager, ESceneType};
+
+use super::NapGameMode;
+
+pub struct FreshGame {
+ pub procedure_mgr: ProcedureManager,
+}
+
+impl FreshGame {
+ pub fn new(start_procedure_id: i32) -> Self {
+ Self {
+ procedure_mgr: ProcedureManager::new(start_procedure_id),
+ }
+ }
+}
+
+impl NapGameMode for FreshGame {
+ fn scene_type(&self) -> ESceneType {
+ ESceneType::Fresh
+ }
+
+ fn scene_info(&self) -> Option {
+ Some(SceneInfo {
+ scene_type: self.scene_type() as u32,
+ fresh_scene_info: Some(FreshSceneInfo {
+ beginner_procedure_id: (self.procedure_mgr.procedure_id() - 1) as u32,
+ }),
+ ..Default::default()
+ })
+ }
+
+ fn dungeon_info(&self) -> Option {
+ None
+ }
+}
diff --git a/nap_gameserver/src/logic/game/frontend.rs b/nap_gameserver/src/logic/game/frontend.rs
new file mode 100644
index 0000000..c18edf4
--- /dev/null
+++ b/nap_gameserver/src/logic/game/frontend.rs
@@ -0,0 +1,90 @@
+use data::tables;
+use proto::*;
+use thiserror::Error;
+
+use crate::logic::{math::Vector3f, time::MainCityTime, ESceneType};
+
+use super::NapGameMode;
+
+pub struct FrontendGame {
+ section_id: u32,
+ frontend_avatar_id: i32,
+ camera_x: u32,
+ camera_y: u32,
+ born_pos: String,
+ main_city_time: MainCityTime,
+ avatar_pos: Vector3f,
+ avatar_rot: Vector3f,
+}
+
+#[derive(Error, Debug)]
+pub enum FrontendGameError {
+ #[error("section id is invalid ({0})")]
+ InvalidSection(u32),
+}
+
+impl FrontendGame {
+ pub fn new(
+ section_id: u32,
+ avatar_id: i32,
+ main_city_time: MainCityTime,
+ avatar_pos: Vector3f,
+ avatar_rot: Vector3f,
+ ) -> Result {
+ let instance = Self {
+ section_id,
+ main_city_time,
+ frontend_avatar_id: avatar_id,
+ camera_x: 0xFFFFFFFF,
+ camera_y: 0xFFFFFFFF,
+ born_pos: Self::get_default_stage_entry_name(section_id)
+ .ok_or(FrontendGameError::InvalidSection(section_id))?,
+ avatar_pos,
+ avatar_rot,
+ };
+
+ tracing::info!("creating new frontend game (section={section_id}, avatar={avatar_id})");
+ Ok(instance)
+ }
+
+ fn get_default_stage_entry_name(section_id: u32) -> Option {
+ tables::section_config_template_tb::iter()
+ .find(|tmpl| tmpl.section_id == section_id)
+ .map(|tmpl| tmpl.primary_entry_name.clone())
+ }
+}
+
+impl NapGameMode for FrontendGame {
+ fn scene_info(&self) -> Option {
+ Some(SceneInfo {
+ scene_type: self.scene_type() as u32,
+ hall_scene_info: Some(HallSceneInfo {
+ section_id: self.section_id,
+ frontend_avatar_id: self.frontend_avatar_id as u32,
+ camera_x: self.camera_x,
+ camera_y: self.camera_y,
+ born_pos: self
+ .avatar_pos
+ .is_zero()
+ .then_some(self.born_pos.clone())
+ .unwrap_or_default(),
+ day_of_week: self.main_city_time.day_of_week.value(),
+ time_of_day: self.main_city_time.time_of_day.value(),
+ position: (!self.avatar_pos.is_zero()).then_some(Transform {
+ position: self.avatar_pos.to_vec(),
+ rotation: self.avatar_rot.to_vec(),
+ }),
+ ..Default::default()
+ }),
+ ..Default::default()
+ })
+ }
+
+ fn dungeon_info(&self) -> Option {
+ None
+ }
+
+ fn scene_type(&self) -> ESceneType {
+ ESceneType::Hall
+ }
+}
diff --git a/nap_gameserver/src/logic/game/hollow.rs b/nap_gameserver/src/logic/game/hollow.rs
new file mode 100644
index 0000000..4c7af02
--- /dev/null
+++ b/nap_gameserver/src/logic/game/hollow.rs
@@ -0,0 +1,75 @@
+use common::util;
+use data::tables;
+use proto::{DungeonInfo, DungeonItemData, FightSceneInfo, SceneInfo, WeatherPoolInfo};
+use thiserror::Error;
+
+use crate::logic::{ELocalPlayType, ESceneType, TimePeriodType, WeatherType};
+
+use super::NapGameMode;
+
+#[derive(Error, Debug)]
+pub enum HollowGameError {
+ #[error("quest id is invalid: {0}")]
+ InvalidQuestId(u32),
+}
+
+pub struct HollowGame {
+ pub quest_id: u32,
+ pub battle_event_id: u32,
+ pub time_period: TimePeriodType,
+ pub weather: WeatherType,
+ pub play_type: ELocalPlayType,
+ pub start_timestamp: i64,
+}
+
+impl HollowGame {
+ pub fn create_training_game(
+ training_quest_id: u32,
+ play_type: ELocalPlayType,
+ ) -> Result {
+ let template = tables::training_quest_template_tb::iter()
+ .find(|tmpl| tmpl.id == training_quest_id)
+ .ok_or(HollowGameError::InvalidQuestId(training_quest_id))?;
+
+ Ok(Self {
+ quest_id: template.id,
+ battle_event_id: template.battle_event_id,
+ time_period: TimePeriodType::Morning,
+ weather: WeatherType::SunShine,
+ start_timestamp: util::cur_timestamp() as i64,
+ play_type,
+ })
+ }
+}
+
+impl NapGameMode for HollowGame {
+ fn scene_type(&self) -> ESceneType {
+ ESceneType::Fight
+ }
+
+ fn scene_info(&self) -> Option {
+ Some(SceneInfo {
+ scene_type: self.scene_type() as u32,
+ battle_event_id: self.battle_event_id,
+ play_type: self.play_type as u32,
+ fight_scene_info: Some(FightSceneInfo {
+ weather_pool: Some(WeatherPoolInfo {
+ time_period: self.time_period.to_string(),
+ weather: self.weather.to_string(),
+ ..Default::default()
+ }),
+ ..Default::default()
+ }),
+ ..Default::default()
+ })
+ }
+
+ fn dungeon_info(&self) -> Option {
+ Some(DungeonInfo {
+ quest_id: self.quest_id,
+ start_timestamp: self.start_timestamp,
+ dungeon_item_data: Some(DungeonItemData::default()),
+ ..Default::default()
+ })
+ }
+}
diff --git a/nap_gameserver/src/logic/game/mod.rs b/nap_gameserver/src/logic/game/mod.rs
new file mode 100644
index 0000000..9e1f2da
--- /dev/null
+++ b/nap_gameserver/src/logic/game/mod.rs
@@ -0,0 +1,60 @@
+mod fresh;
+mod frontend;
+mod hollow;
+pub use fresh::*;
+pub use frontend::*;
+pub use hollow::*;
+
+use proto::{DungeonInfo, SceneInfo, WorldInitScNotify};
+use thiserror::Error;
+
+use super::{procedure::ProcedureError, ESceneType};
+
+#[derive(Default)]
+pub enum GameInstance {
+ Frontend(FrontendGame),
+ Fresh(FreshGame),
+ Hollow(HollowGame),
+ #[default]
+ Null,
+}
+
+#[derive(Error, Debug)]
+pub enum LogicError {
+ #[error("game instance is NULL!")]
+ GameIsNull,
+ #[error("frontend error: {0}")]
+ Frontend(#[from] FrontendGameError),
+ #[error("procedure error: {0}")]
+ Procedure(#[from] ProcedureError),
+ #[error("hollow error: {0}")]
+ Hollow(#[from] HollowGameError),
+}
+
+impl GameInstance {
+ pub fn is_null(&self) -> bool {
+ matches!(self, Self::Null)
+ }
+
+ pub fn create_world_init_notify(&self) -> Result {
+ Ok(Self::world_init_sc_notify(match self {
+ Self::Frontend(game) => game,
+ Self::Fresh(game) => game,
+ Self::Hollow(game) => game,
+ Self::Null => return Err(LogicError::GameIsNull),
+ }))
+ }
+
+ fn world_init_sc_notify(game: &dyn NapGameMode) -> WorldInitScNotify {
+ WorldInitScNotify {
+ scene_info: game.scene_info(),
+ dungeon_info: game.dungeon_info(),
+ }
+ }
+}
+
+pub trait NapGameMode {
+ fn scene_type(&self) -> ESceneType;
+ fn scene_info(&self) -> Option;
+ fn dungeon_info(&self) -> Option;
+}
diff --git a/nap_gameserver/src/logic/item/item_model.rs b/nap_gameserver/src/logic/item/item_model.rs
new file mode 100644
index 0000000..02ffb40
--- /dev/null
+++ b/nap_gameserver/src/logic/item/item_model.rs
@@ -0,0 +1,47 @@
+use super::ResourceItem;
+use proto::ItemModelBin;
+
+pub struct ItemModel {
+ pub resources: Vec,
+}
+
+impl ItemModel {
+ pub fn from_bin(bin: ItemModelBin) -> Self {
+ Self {
+ resources: bin
+ .resource_list
+ .into_iter()
+ .map(ResourceItem::from_bin)
+ .collect(),
+ }
+ }
+
+ pub fn to_bin(&self) -> ItemModelBin {
+ ItemModelBin {
+ resource_list: self.resources.iter().map(ResourceItem::to_bin).collect(),
+ }
+ }
+
+ pub fn add_resource(&mut self, template_id: u32, num: u32) {
+ if let Some(item) = self
+ .resources
+ .iter_mut()
+ .find(|item| item.template_id == template_id)
+ {
+ item.num += num as i32;
+ } else {
+ self.resources.push(ResourceItem {
+ template_id,
+ num: num as i32,
+ });
+ }
+ }
+}
+
+impl Default for ItemModel {
+ fn default() -> Self {
+ Self {
+ resources: Vec::new(),
+ }
+ }
+}
diff --git a/nap_gameserver/src/logic/item/mod.rs b/nap_gameserver/src/logic/item/mod.rs
new file mode 100644
index 0000000..a427a17
--- /dev/null
+++ b/nap_gameserver/src/logic/item/mod.rs
@@ -0,0 +1,5 @@
+mod item_model;
+mod resource;
+
+pub use item_model::ItemModel;
+pub use resource::ResourceItem;
diff --git a/nap_gameserver/src/logic/item/resource.rs b/nap_gameserver/src/logic/item/resource.rs
new file mode 100644
index 0000000..6c07168
--- /dev/null
+++ b/nap_gameserver/src/logic/item/resource.rs
@@ -0,0 +1,29 @@
+use proto::{Resource, ResourceItemBin};
+
+pub struct ResourceItem {
+ pub template_id: u32,
+ pub num: i32,
+}
+
+impl ResourceItem {
+ pub fn from_bin(bin: ResourceItemBin) -> Self {
+ Self {
+ template_id: bin.template_id,
+ num: bin.num,
+ }
+ }
+
+ pub fn to_bin(&self) -> ResourceItemBin {
+ ResourceItemBin {
+ template_id: self.template_id,
+ num: self.num,
+ }
+ }
+
+ pub fn to_client(&self) -> Resource {
+ Resource {
+ template_id: self.template_id,
+ num: self.num,
+ }
+ }
+}
diff --git a/nap_gameserver/src/logic/math.rs b/nap_gameserver/src/logic/math.rs
new file mode 100644
index 0000000..9e7720e
--- /dev/null
+++ b/nap_gameserver/src/logic/math.rs
@@ -0,0 +1,24 @@
+#[derive(Default, Clone, Debug)]
+pub struct Vector3f {
+ pub x: f64,
+ pub y: f64,
+ pub z: f64,
+}
+
+impl Vector3f {
+ pub fn from_vec(v: Vec) -> Self {
+ Self {
+ x: v.get(0).cloned().unwrap_or_default(),
+ y: v.get(1).cloned().unwrap_or_default(),
+ z: v.get(2).cloned().unwrap_or_default(),
+ }
+ }
+
+ pub fn to_vec(&self) -> Vec {
+ vec![self.x, self.y, self.z]
+ }
+
+ pub fn is_zero(&self) -> bool {
+ self.x == 0.0 && self.y == 0.0 && self.z == 0.0
+ }
+}
diff --git a/nap_gameserver/src/logic/mod.rs b/nap_gameserver/src/logic/mod.rs
new file mode 100644
index 0000000..8a70b1f
--- /dev/null
+++ b/nap_gameserver/src/logic/mod.rs
@@ -0,0 +1,11 @@
+mod enums;
+pub mod game;
+pub mod item;
+pub mod math;
+pub mod player;
+pub mod procedure;
+pub mod role;
+pub mod time;
+
+pub use enums::*;
+pub use player::Player;
diff --git a/nap_gameserver/src/logic/player/basic_data_model.rs b/nap_gameserver/src/logic/player/basic_data_model.rs
new file mode 100644
index 0000000..3bb10c0
--- /dev/null
+++ b/nap_gameserver/src/logic/player/basic_data_model.rs
@@ -0,0 +1,62 @@
+use proto::{BasicDataModelBin, PlayerBasicInfo};
+
+pub struct BasicDataModel {
+ pub level: u32,
+ pub exp: u32,
+ pub profile_icon: u32,
+ pub nick_name: Option,
+ pub frontend_avatar_id: i32,
+ pub beginner_procedure_id: i32,
+}
+
+impl Default for BasicDataModel {
+ fn default() -> Self {
+ Self {
+ level: 1,
+ exp: 0,
+ profile_icon: 3200000,
+ nick_name: None,
+ frontend_avatar_id: 0,
+ beginner_procedure_id: 1,
+ }
+ }
+}
+
+impl BasicDataModel {
+ pub fn player_basic_info(&self) -> PlayerBasicInfo {
+ PlayerBasicInfo {
+ nick_name: self.nick_name.clone().unwrap_or_default(),
+ exp: self.exp,
+ level: self.level,
+ avatar_id: self.frontend_avatar_id as u32,
+ frontend_avatar_id: self.frontend_avatar_id as u32,
+ kbjleelonfe: self.profile_icon,
+ ..Default::default()
+ }
+ }
+
+ pub fn from_bin(bin: BasicDataModelBin) -> Self {
+ Self {
+ level: bin.level,
+ exp: bin.exp,
+ profile_icon: bin.profile_icon,
+ frontend_avatar_id: bin.frontend_avatar_id,
+ beginner_procedure_id: bin.beginner_procedure_id,
+ nick_name: match bin.nick_name.is_empty() {
+ true => None,
+ false => Some(bin.nick_name),
+ },
+ }
+ }
+
+ pub fn to_bin(&self) -> BasicDataModelBin {
+ BasicDataModelBin {
+ level: self.level,
+ exp: self.exp,
+ profile_icon: self.profile_icon,
+ frontend_avatar_id: self.frontend_avatar_id,
+ nick_name: self.nick_name.clone().unwrap_or_default(),
+ beginner_procedure_id: self.beginner_procedure_id,
+ }
+ }
+}
diff --git a/nap_gameserver/src/logic/player/lock_model.rs b/nap_gameserver/src/logic/player/lock_model.rs
new file mode 100644
index 0000000..63ba690
--- /dev/null
+++ b/nap_gameserver/src/logic/player/lock_model.rs
@@ -0,0 +1,37 @@
+use std::collections::BTreeSet;
+
+use proto::{LockModelBin, UnlockData};
+
+#[derive(Default)]
+pub struct LockModel {
+ unlock_list: BTreeSet,
+}
+
+impl LockModel {
+ pub fn from_bin(bin: LockModelBin) -> Self {
+ Self {
+ unlock_list: bin.unlock_list.into_iter().collect(),
+ }
+ }
+
+ pub fn to_bin(&self) -> LockModelBin {
+ LockModelBin {
+ unlock_list: self.unlock_list.clone().into_iter().collect(),
+ }
+ }
+
+ pub fn to_client(&self) -> UnlockData {
+ UnlockData {
+ unlock_id_list: self.unlock_list.clone().into_iter().collect(),
+ ..Default::default()
+ }
+ }
+
+ pub fn add_unlock(&mut self, id: i32) {
+ self.unlock_list.insert(id);
+ }
+
+ pub fn is_unlock(&self, id: i32) -> bool {
+ self.unlock_list.contains(&id)
+ }
+}
diff --git a/nap_gameserver/src/logic/player/main_city_model.rs b/nap_gameserver/src/logic/player/main_city_model.rs
new file mode 100644
index 0000000..eda8df5
--- /dev/null
+++ b/nap_gameserver/src/logic/player/main_city_model.rs
@@ -0,0 +1,50 @@
+use proto::{MainCityModelBin, TransformBin};
+
+use super::{math::Vector3f, time::MainCityTime};
+
+pub struct MainCityModel {
+ pub position: Vector3f,
+ pub rotation: Vector3f,
+ pub main_city_time: MainCityTime,
+ pub section_id: u32,
+}
+
+impl MainCityModel {
+ pub fn update_position(&mut self, pos: Vec, rot: Vec) {
+ self.position = Vector3f::from_vec(pos);
+ self.rotation = Vector3f::from_vec(rot);
+ }
+
+ pub fn to_bin(&self) -> MainCityModelBin {
+ MainCityModelBin {
+ transform: Some(TransformBin {
+ position: self.position.to_vec(),
+ rotation: self.position.to_vec(),
+ }),
+ time: Some(self.main_city_time.to_bin()),
+ section_id: self.section_id,
+ }
+ }
+
+ pub fn from_bin(bin: MainCityModelBin) -> Self {
+ let transform = bin.transform.unwrap_or_default();
+
+ Self {
+ position: Vector3f::from_vec(transform.position),
+ rotation: Vector3f::from_vec(transform.rotation),
+ main_city_time: bin.time.map(MainCityTime::from_bin).unwrap_or_default(),
+ section_id: bin.section_id,
+ }
+ }
+}
+
+impl Default for MainCityModel {
+ fn default() -> Self {
+ Self {
+ position: Vector3f::default(),
+ rotation: Vector3f::default(),
+ main_city_time: MainCityTime::default(),
+ section_id: 1,
+ }
+ }
+}
diff --git a/nap_gameserver/src/logic/player/mod.rs b/nap_gameserver/src/logic/player/mod.rs
new file mode 100644
index 0000000..c54a425
--- /dev/null
+++ b/nap_gameserver/src/logic/player/mod.rs
@@ -0,0 +1,12 @@
+use super::*;
+
+mod basic_data_model;
+mod lock_model;
+mod main_city_model;
+mod player;
+mod player_mgr;
+
+pub use basic_data_model::BasicDataModel;
+pub use lock_model::LockModel;
+pub use player::Player;
+pub use player_mgr::PlayerManager;
diff --git a/nap_gameserver/src/logic/player/player.rs b/nap_gameserver/src/logic/player/player.rs
new file mode 100644
index 0000000..3336b34
--- /dev/null
+++ b/nap_gameserver/src/logic/player/player.rs
@@ -0,0 +1,100 @@
+use data::tables;
+use proto::{ItemStatic, PlayerDataBin, Retcode};
+
+use super::game::{FrontendGame, GameInstance, LogicError};
+use super::item::ItemModel;
+use super::main_city_model::MainCityModel;
+use super::role::RoleModel;
+use super::{BasicDataModel, LockModel};
+
+#[derive(Default)]
+pub struct Player {
+ current_session_id: Option,
+ pub game_instance: GameInstance,
+ pub basic_data_model: BasicDataModel,
+ pub lock_model: LockModel,
+ pub role_model: RoleModel,
+ pub item_model: ItemModel,
+ pub main_city_model: MainCityModel,
+}
+
+impl Player {
+ const MAIN_AVATAR_IDS: [i32; 2] = [2011, 2021];
+
+ pub fn save_to_bin(&self) -> PlayerDataBin {
+ PlayerDataBin {
+ basic_data_model: Some(self.basic_data_model.to_bin()),
+ lock_model: Some(self.lock_model.to_bin()),
+ role_model: Some(self.role_model.to_bin()),
+ item_model: Some(self.item_model.to_bin()),
+ main_city_model: Some(self.main_city_model.to_bin()),
+ }
+ }
+
+ pub fn load_from_bin(bin: PlayerDataBin) -> Self {
+ Self {
+ basic_data_model: bin
+ .basic_data_model
+ .map(BasicDataModel::from_bin)
+ .unwrap_or_default(),
+ lock_model: bin.lock_model.map(LockModel::from_bin).unwrap_or_default(),
+ role_model: bin.role_model.map(RoleModel::from_bin).unwrap_or_default(),
+ item_model: bin.item_model.map(ItemModel::from_bin).unwrap_or_default(),
+ main_city_model: bin
+ .main_city_model
+ .map(MainCityModel::from_bin)
+ .unwrap_or_default(),
+ ..Default::default()
+ }
+ }
+
+ pub fn on_login(&mut self) {
+ tables::unlock_config_template_tb::iter()
+ .for_each(|tmpl| self.lock_model.add_unlock(tmpl.id))
+ }
+
+ pub fn on_first_login(&mut self) {
+ self.item_model
+ .add_resource(ItemStatic::FrontendGold as u32, 1_000_000);
+ self.item_model
+ .add_resource(ItemStatic::GameDiamond as u32, 1_000_000);
+ self.item_model.add_resource(ItemStatic::Energy as u32, 240);
+ }
+
+ pub fn init_frontend_game(&mut self) -> Result<(), LogicError> {
+ let main_city = &self.main_city_model;
+ self.game_instance = GameInstance::Frontend(
+ FrontendGame::new(
+ main_city.section_id,
+ self.basic_data_model.frontend_avatar_id,
+ main_city.main_city_time.clone(),
+ main_city.position.clone(),
+ main_city.rotation.clone(),
+ )
+ .map_err(LogicError::from)?,
+ );
+
+ Ok(())
+ }
+
+ pub fn set_frontend_avatar(&mut self, id: i32) -> Result<(), Retcode> {
+ (self.basic_data_model.frontend_avatar_id == 0)
+ .then_some(())
+ .ok_or(Retcode::RetFail)?;
+
+ (Self::MAIN_AVATAR_IDS.contains(&id))
+ .then_some(())
+ .ok_or(Retcode::RetFail)?;
+
+ self.basic_data_model.frontend_avatar_id = id;
+ Ok(())
+ }
+
+ pub fn set_current_session(&mut self, id: u64) {
+ self.current_session_id = Some(id);
+ }
+
+ pub fn current_session_id(&self) -> Option {
+ self.current_session_id
+ }
+}
diff --git a/nap_gameserver/src/logic/player/player_mgr.rs b/nap_gameserver/src/logic/player/player_mgr.rs
new file mode 100644
index 0000000..10e568d
--- /dev/null
+++ b/nap_gameserver/src/logic/player/player_mgr.rs
@@ -0,0 +1,142 @@
+use std::sync::Arc;
+
+use dashmap::DashMap;
+use prost::Message;
+use proto::{PlayerDataBin, Retcode};
+use sqlx::PgPool;
+use tokio::sync::Mutex;
+
+use crate::database::{self, DbError};
+
+use super::Player;
+
+pub type SharedPlayerLock = Arc>;
+
+pub struct PlayerManager {
+ players: DashMap,
+ pg_pool: PgPool,
+}
+
+impl PlayerManager {
+ pub fn new(pg_pool: PgPool) -> Self {
+ Self {
+ players: DashMap::new(),
+ pg_pool,
+ }
+ }
+
+ pub async fn authorize(
+ &self,
+ account_uid: &str,
+ token: &str,
+ platform_type: u32,
+ ) -> Result {
+ let combo_token =
+ match database::select_combo_token_by_account(&self.pg_pool, account_uid).await {
+ Ok(row) => row.token,
+ Err(_) => return Err(Retcode::RetFail),
+ };
+
+ (combo_token == token)
+ .then_some(())
+ .ok_or(Retcode::RetFail)?;
+
+ let player_uid = match database::select_player_uid_by_account(&self.pg_pool, account_uid)
+ .await
+ {
+ Ok(row) => row.uid,
+ Err(DbError::NotFound) => {
+ database::insert_player_uid_by_account(&self.pg_pool, account_uid, platform_type)
+ .await
+ .map_err(|err| {
+ tracing::error!("failed to insert player_uid: {err}");
+ Retcode::RetFail
+ })?
+ .uid
+ }
+ Err(_) => return Err(Retcode::RetFail),
+ } as u32;
+
+ Ok(player_uid)
+ }
+
+ pub async fn get_player(&self, uid: u32) -> Option {
+ if let Some(player) = self.players.get(&uid).map(|a| (*a).clone()) {
+ return Some(player);
+ }
+
+ let player_bin_data =
+ match database::select_player_data_by_uid(&self.pg_pool, uid as i32).await {
+ Ok(row) => Some(row.bin_data),
+ Err(DbError::NotFound) => None,
+ Err(DbError::SqlxError(err)) => {
+ tracing::error!("SQL error: {err}");
+ return None;
+ }
+ };
+
+ let player = match player_bin_data {
+ Some(bin_data) => match PlayerDataBin::decode(&*bin_data) {
+ Ok(bin) => Player::load_from_bin(bin),
+ Err(err) => {
+ tracing::error!("failed to decode PlayerDataBin for uid {uid}, error: {err}");
+ return None;
+ }
+ },
+ None => {
+ let mut player = Player::default();
+ player.on_first_login();
+
+ match database::insert_player_data_by_uid(
+ &self.pg_pool,
+ uid as i32,
+ player.save_to_bin().encode_to_vec(),
+ )
+ .await
+ {
+ Ok(()) => player,
+ Err(err) => {
+ tracing::error!("failed to insert player data, uid: {uid}, error: {err}");
+ return None;
+ }
+ }
+ }
+ };
+
+ self.players.insert(uid, Arc::new(Mutex::new(player)));
+ self.players.get(&uid).map(|a| (*a).clone())
+ }
+
+ pub async fn save(&self, player_uid: u32) {
+ let Some(player_lock) = self.players.get(&player_uid) else {
+ tracing::warn!("save: player with uid {player_uid} not found");
+ return;
+ };
+
+ let player = player_lock.lock().await;
+ self.do_save(player_uid, &*player).await;
+ }
+
+ pub async fn save_and_remove(&self, player_uid: u32) {
+ let Some((_, player_lock)) = self.players.remove(&player_uid) else {
+ tracing::warn!("save_and_remove: player with uid {player_uid} not found");
+ return;
+ };
+
+ let player = player_lock.lock().await;
+ self.do_save(player_uid, &*player).await;
+ }
+
+ async fn do_save(&self, uid: u32, player: &Player) {
+ let bin = player.save_to_bin();
+
+ if let Err(err) =
+ database::update_player_data_by_uid(&self.pg_pool, uid as i32, bin.encode_to_vec())
+ .await
+ {
+ tracing::error!("failed to update player data: {err}");
+ }
+
+ tracing::info!("player data flushed to database, uid: {uid}");
+ }
+}
diff --git a/nap_gameserver/src/logic/procedure/battle.rs b/nap_gameserver/src/logic/procedure/battle.rs
new file mode 100644
index 0000000..379f087
--- /dev/null
+++ b/nap_gameserver/src/logic/procedure/battle.rs
@@ -0,0 +1,58 @@
+use super::{ProcedureAction, ProcedureBase, ProcedureError, ProcedureState, ProcedureType};
+
+pub struct ProcedureBattle {
+ id: i32,
+ state: ProcedureState,
+}
+
+impl ProcedureBattle {
+ pub fn new(id: i32) -> Self {
+ Self {
+ id,
+ state: ProcedureState::Init,
+ }
+ }
+}
+
+impl ProcedureBase for ProcedureBattle {
+ fn id(&self) -> i32 {
+ self.id
+ }
+
+ fn procedure_type(&self) -> ProcedureType {
+ ProcedureType::Battle
+ }
+
+ fn on_action(&mut self, action: ProcedureAction) -> Result {
+ match action {
+ ProcedureAction::BeginnerBattleBegin => {
+ (self.state == ProcedureState::Init)
+ .then_some(())
+ .ok_or(ProcedureError::InvalidState(action, self.state))?;
+
+ self.state = ProcedureState::Running;
+ }
+ ProcedureAction::BeginnerBattleEnd => {
+ (self.state == ProcedureState::Running)
+ .then_some(())
+ .ok_or(ProcedureError::InvalidState(action, self.state))?;
+
+ self.state = ProcedureState::Finish;
+ }
+ ProcedureAction::PerformTrigger => (),
+ ProcedureAction::PerformEnd => (),
+ _ => {
+ return Err(ProcedureError::UnsupportedAction(
+ action,
+ self.procedure_type(),
+ ))
+ }
+ }
+
+ Ok(self.state)
+ }
+
+ fn is_finished(&self) -> bool {
+ self.state == ProcedureState::Finish
+ }
+}
diff --git a/nap_gameserver/src/logic/procedure/mod.rs b/nap_gameserver/src/logic/procedure/mod.rs
new file mode 100644
index 0000000..a74eb11
--- /dev/null
+++ b/nap_gameserver/src/logic/procedure/mod.rs
@@ -0,0 +1,102 @@
+mod battle;
+mod plot_play;
+mod procedure_mgr;
+mod select_role;
+
+pub use battle::ProcedureBattle;
+pub use plot_play::ProcedurePlotPlay;
+pub use procedure_mgr::ProcedureManager;
+pub use select_role::ProcedureSelectRole;
+
+use data::tables::{self, ProcedureConfigTemplate};
+use num_enum::TryFromPrimitive;
+use thiserror::Error;
+
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug)]
+pub enum ProcedureState {
+ Init,
+ Running,
+ Finish,
+}
+
+#[derive(Clone, Copy, PartialEq, Eq, Debug, TryFromPrimitive)]
+#[repr(u32)]
+pub enum ProcedureType {
+ Battle = 1,
+ PlotPlay = 2,
+ SelectRole = 4,
+}
+
+#[derive(Clone, Copy, PartialEq, Eq, Debug)]
+pub enum ProcedureAction {
+ PerformTrigger,
+ PerformEnd,
+ SelectRole,
+ BeginnerBattleBegin,
+ BeginnerBattleEnd,
+}
+
+#[derive(Error, Debug)]
+pub enum ProcedureError {
+ #[error("action {0:?} is not allowed for procedure of type {1:?}")]
+ UnsupportedAction(ProcedureAction, ProcedureType),
+ #[error("action {0:?} is not allowed in current state: {1:?}")]
+ InvalidState(ProcedureAction, ProcedureState),
+ #[error("can't advance procedure because it's not finished")]
+ NotFinished,
+ #[error("trying to complete procedure: {0}, current procedure: {1}")]
+ InvalidProcedureId(i32, i32),
+ #[error("current procedure is NULL!")]
+ ProcedureIsNull,
+}
+
+pub trait ProcedureBase {
+ fn id(&self) -> i32;
+ fn procedure_type(&self) -> ProcedureType;
+
+ fn get_next_id(&self) -> Option<&i32> {
+ let config = tables::procedure_config_template_tb::iter()
+ .find(|tmpl| tmpl.procedure_id == self.id())
+ .unwrap();
+
+ config.jump_tos.iter().next()
+ }
+
+ fn on_action(&mut self, action: ProcedureAction) -> Result;
+ fn is_finished(&self) -> bool;
+}
+
+pub enum Procedure {
+ Battle(ProcedureBattle),
+ PlotPlay(ProcedurePlotPlay),
+ SelectRole(ProcedureSelectRole),
+}
+
+impl Procedure {
+ pub fn new(template: &ProcedureConfigTemplate) -> Self {
+ use ProcedureType::*;
+ let procedure_type = ProcedureType::try_from_primitive(template.procedure_type).unwrap();
+
+ match procedure_type {
+ Battle => Procedure::Battle(ProcedureBattle::new(template.procedure_id)),
+ PlotPlay => Procedure::PlotPlay(ProcedurePlotPlay::new(template.procedure_id)),
+ SelectRole => Procedure::SelectRole(ProcedureSelectRole::new(template.procedure_id)),
+ }
+ }
+
+ pub fn base(&self) -> &dyn ProcedureBase {
+ match self {
+ Self::Battle(proc) => proc,
+ Self::PlotPlay(proc) => proc,
+ Self::SelectRole(proc) => proc,
+ }
+ }
+
+ pub fn base_mut(&mut self) -> &mut dyn ProcedureBase {
+ match self {
+ Self::Battle(proc) => proc,
+ Self::PlotPlay(proc) => proc,
+ Self::SelectRole(proc) => proc,
+ }
+ }
+}
diff --git a/nap_gameserver/src/logic/procedure/plot_play.rs b/nap_gameserver/src/logic/procedure/plot_play.rs
new file mode 100644
index 0000000..c9bd403
--- /dev/null
+++ b/nap_gameserver/src/logic/procedure/plot_play.rs
@@ -0,0 +1,56 @@
+use super::{ProcedureAction, ProcedureBase, ProcedureError, ProcedureState, ProcedureType};
+
+pub struct ProcedurePlotPlay {
+ id: i32,
+ state: ProcedureState,
+}
+
+impl ProcedurePlotPlay {
+ pub fn new(id: i32) -> Self {
+ Self {
+ id,
+ state: ProcedureState::Init,
+ }
+ }
+}
+
+impl ProcedureBase for ProcedurePlotPlay {
+ fn id(&self) -> i32 {
+ self.id
+ }
+
+ fn procedure_type(&self) -> ProcedureType {
+ ProcedureType::PlotPlay
+ }
+
+ fn on_action(&mut self, action: ProcedureAction) -> Result {
+ match action {
+ ProcedureAction::PerformTrigger => {
+ (self.state == ProcedureState::Init)
+ .then_some(())
+ .ok_or(ProcedureError::InvalidState(action, self.state))?;
+
+ self.state = ProcedureState::Running;
+ }
+ ProcedureAction::PerformEnd => {
+ (self.state == ProcedureState::Running)
+ .then_some(())
+ .ok_or(ProcedureError::InvalidState(action, self.state))?;
+
+ self.state = ProcedureState::Finish
+ }
+ _ => {
+ return Err(ProcedureError::UnsupportedAction(
+ action,
+ self.procedure_type(),
+ ))
+ }
+ }
+
+ Ok(self.state)
+ }
+
+ fn is_finished(&self) -> bool {
+ self.state >= ProcedureState::Running
+ }
+}
diff --git a/nap_gameserver/src/logic/procedure/procedure_mgr.rs b/nap_gameserver/src/logic/procedure/procedure_mgr.rs
new file mode 100644
index 0000000..70c8680
--- /dev/null
+++ b/nap_gameserver/src/logic/procedure/procedure_mgr.rs
@@ -0,0 +1,66 @@
+use data::tables;
+
+use super::{Procedure, ProcedureAction, ProcedureError};
+
+pub struct ProcedureManager {
+ cur_procedure_id: i32,
+ procedures: Vec,
+}
+
+impl ProcedureManager {
+ pub fn new(start_procedure_id: i32) -> Self {
+ Self {
+ cur_procedure_id: start_procedure_id,
+ procedures: tables::procedure_config_template_tb::iter()
+ .filter(|tmpl| tmpl.procedure_id >= start_procedure_id)
+ .map(Procedure::new)
+ .collect(),
+ }
+ }
+
+ pub fn try_complete_procedure(&mut self, procedure_id: i32) -> Result<(), ProcedureError> {
+ (self.cur_procedure_id == procedure_id)
+ .then_some(())
+ .ok_or(ProcedureError::InvalidProcedureId(
+ procedure_id,
+ self.cur_procedure_id,
+ ))?;
+
+ let procedure = self
+ .procedures
+ .iter()
+ .find(|proc| proc.base().id() == procedure_id)
+ .ok_or(ProcedureError::ProcedureIsNull)?;
+
+ if procedure.base().is_finished() {
+ self.cur_procedure_id = procedure.base().get_next_id().cloned().unwrap_or(-1);
+ Ok(())
+ } else {
+ Err(ProcedureError::NotFinished)
+ }
+ }
+
+ pub fn on_action(&mut self, action: ProcedureAction) -> Result<(), ProcedureError> {
+ let procedure = self
+ .procedures
+ .iter_mut()
+ .find(|proc| proc.base().id() == self.cur_procedure_id)
+ .ok_or(ProcedureError::ProcedureIsNull)?;
+
+ let state = procedure.base_mut().on_action(action)?;
+ tracing::info!(
+ "procedure action {action:?} performed, state: {state:?}, procedure id: {}",
+ self.cur_procedure_id
+ );
+
+ Ok(())
+ }
+
+ pub fn procedure_id(&self) -> i32 {
+ self.cur_procedure_id
+ }
+
+ pub fn is_end(&self) -> bool {
+ self.cur_procedure_id == -1
+ }
+}
diff --git a/nap_gameserver/src/logic/procedure/select_role.rs b/nap_gameserver/src/logic/procedure/select_role.rs
new file mode 100644
index 0000000..4cb2669
--- /dev/null
+++ b/nap_gameserver/src/logic/procedure/select_role.rs
@@ -0,0 +1,51 @@
+use super::{ProcedureAction, ProcedureBase, ProcedureError, ProcedureState, ProcedureType};
+
+pub struct ProcedureSelectRole {
+ id: i32,
+ state: ProcedureState,
+}
+
+impl ProcedureSelectRole {
+ pub fn new(id: i32) -> Self {
+ Self {
+ id,
+ state: ProcedureState::Init,
+ }
+ }
+}
+
+impl ProcedureBase for ProcedureSelectRole {
+ fn id(&self) -> i32 {
+ self.id
+ }
+
+ fn procedure_type(&self) -> ProcedureType {
+ ProcedureType::SelectRole
+ }
+
+ fn on_action(&mut self, action: ProcedureAction) -> Result {
+ match action {
+ ProcedureAction::SelectRole => {
+ (self.state == ProcedureState::Init)
+ .then_some(())
+ .ok_or(ProcedureError::InvalidState(action, self.state))?;
+
+ self.state = ProcedureState::Finish;
+ }
+ ProcedureAction::PerformTrigger => (),
+ ProcedureAction::PerformEnd => (),
+ _ => {
+ return Err(ProcedureError::UnsupportedAction(
+ action,
+ self.procedure_type(),
+ ))
+ }
+ }
+
+ Ok(self.state)
+ }
+
+ fn is_finished(&self) -> bool {
+ self.state == ProcedureState::Finish
+ }
+}
diff --git a/nap_gameserver/src/logic/role/avatar.rs b/nap_gameserver/src/logic/role/avatar.rs
new file mode 100644
index 0000000..03e8b66
--- /dev/null
+++ b/nap_gameserver/src/logic/role/avatar.rs
@@ -0,0 +1,88 @@
+use proto::{AvatarBin, AvatarInfo, AvatarSkillInfo};
+
+use super::AvatarSkill;
+
+pub const AVATAR_TALENT_COUNT: usize = 6;
+pub struct Avatar {
+ pub template_id: u32,
+ pub level: u32,
+ pub exp: u32,
+ pub star: u32,
+ pub rank: u32,
+ pub unlocked_talent_num: u32,
+ pub skill_list: Vec,
+ pub talent_switch: [bool; AVATAR_TALENT_COUNT],
+}
+
+impl Avatar {
+ pub fn new(template_id: u32) -> Self {
+ Self {
+ template_id,
+ level: 60,
+ exp: 0,
+ star: 0,
+ rank: 6,
+ unlocked_talent_num: 6,
+ skill_list: (0..=6)
+ .map(|st| AvatarSkill {
+ skill_type: st,
+ level: 1,
+ })
+ .collect(),
+ talent_switch: [true; AVATAR_TALENT_COUNT],
+ }
+ }
+
+ pub fn from_bin(bin: AvatarBin) -> Self {
+ Self {
+ template_id: bin.template_id,
+ level: bin.level,
+ exp: bin.exp,
+ star: bin.star,
+ rank: bin.rank,
+ unlocked_talent_num: bin.unlocked_talent_num,
+ skill_list: bin
+ .avatar_skill_list
+ .into_iter()
+ .map(AvatarSkill::from_bin)
+ .collect(),
+ talent_switch: bin
+ .talent_switch_list
+ .try_into()
+ .unwrap_or([false; AVATAR_TALENT_COUNT]),
+ }
+ }
+
+ pub fn to_bin(&self) -> AvatarBin {
+ AvatarBin {
+ template_id: self.template_id,
+ exp: self.exp,
+ level: self.level,
+ star: self.star,
+ rank: self.rank,
+ unlocked_talent_num: self.unlocked_talent_num,
+ avatar_skill_list: self.skill_list.iter().map(AvatarSkill::to_bin).collect(),
+ talent_switch_list: self.talent_switch.to_vec(),
+ }
+ }
+
+ pub fn to_client(&self) -> AvatarInfo {
+ AvatarInfo {
+ template_id: self.template_id,
+ level: self.level,
+ skill_list: self
+ .skill_list
+ .iter()
+ .map(|s| AvatarSkillInfo {
+ skill_type: s.skill_type,
+ level: s.level,
+ })
+ .collect(),
+ exp: self.exp, // exp?
+ rank: self.rank,
+ talent_switch_list: self.talent_switch.to_vec(),
+ unlocked_talent_num: self.unlocked_talent_num,
+ ..Default::default()
+ }
+ }
+}
diff --git a/nap_gameserver/src/logic/role/mod.rs b/nap_gameserver/src/logic/role/mod.rs
new file mode 100644
index 0000000..a830fe9
--- /dev/null
+++ b/nap_gameserver/src/logic/role/mod.rs
@@ -0,0 +1,7 @@
+mod avatar;
+mod role_model;
+mod skill;
+
+pub use avatar::Avatar;
+pub use role_model::RoleModel;
+pub use skill::AvatarSkill;
diff --git a/nap_gameserver/src/logic/role/role_model.rs b/nap_gameserver/src/logic/role/role_model.rs
new file mode 100644
index 0000000..a1d57fd
--- /dev/null
+++ b/nap_gameserver/src/logic/role/role_model.rs
@@ -0,0 +1,34 @@
+use data::tables;
+use proto::RoleModelBin;
+
+use crate::logic::role::Avatar;
+
+pub struct RoleModel {
+ pub avatar_list: Vec,
+}
+
+impl Default for RoleModel {
+ fn default() -> Self {
+ Self {
+ avatar_list: tables::avatar_base_template_tb::iter()
+ .map(|a| a.id)
+ .filter(|tmpl_id| *tmpl_id < 2000)
+ .map(|tmpl_id| Avatar::new(tmpl_id))
+ .collect(),
+ }
+ }
+}
+
+impl RoleModel {
+ pub fn from_bin(bin: RoleModelBin) -> Self {
+ Self {
+ avatar_list: bin.avatar_list.into_iter().map(Avatar::from_bin).collect(),
+ }
+ }
+
+ pub fn to_bin(&self) -> RoleModelBin {
+ RoleModelBin {
+ avatar_list: self.avatar_list.iter().map(Avatar::to_bin).collect(),
+ }
+ }
+}
diff --git a/nap_gameserver/src/logic/role/skill.rs b/nap_gameserver/src/logic/role/skill.rs
new file mode 100644
index 0000000..9bc95da
--- /dev/null
+++ b/nap_gameserver/src/logic/role/skill.rs
@@ -0,0 +1,22 @@
+use proto::AvatarSkillBin;
+
+pub struct AvatarSkill {
+ pub skill_type: u32,
+ pub level: u32,
+}
+
+impl AvatarSkill {
+ pub fn from_bin(bin: AvatarSkillBin) -> Self {
+ Self {
+ skill_type: bin.skill_type,
+ level: bin.level,
+ }
+ }
+
+ pub fn to_bin(&self) -> AvatarSkillBin {
+ AvatarSkillBin {
+ skill_type: self.skill_type,
+ level: self.level,
+ }
+ }
+}
diff --git a/nap_gameserver/src/logic/time.rs b/nap_gameserver/src/logic/time.rs
new file mode 100644
index 0000000..0bba17d
--- /dev/null
+++ b/nap_gameserver/src/logic/time.rs
@@ -0,0 +1,102 @@
+use proto::MainCityTimeBin;
+
+#[derive(Clone)]
+pub struct MainCityTime {
+ pub day_of_week: DayOfWeek,
+ pub time_of_day: TimeOfDay,
+}
+
+impl MainCityTime {
+ const DEFAULT_DAY: u32 = 1;
+ const DEFAULT_TIME: u32 = 1080;
+
+ pub fn tick(&mut self) {
+ if self.time_of_day.tick() {
+ self.day_of_week.next();
+ }
+ }
+
+ pub fn fast_forward(&mut self, minutes: u32) {
+ let days_passed = self.time_of_day.fast_forward(minutes);
+ self.day_of_week.fast_forward(days_passed)
+ }
+
+ pub fn to_bin(&self) -> MainCityTimeBin {
+ MainCityTimeBin {
+ minutes: self.time_of_day.value(),
+ day: self.day_of_week.value(),
+ }
+ }
+
+ pub fn from_bin(bin: MainCityTimeBin) -> Self {
+ Self {
+ time_of_day: TimeOfDay::new(bin.minutes),
+ day_of_week: DayOfWeek::new(bin.day),
+ }
+ }
+}
+
+impl Default for MainCityTime {
+ fn default() -> Self {
+ Self {
+ day_of_week: DayOfWeek::new(Self::DEFAULT_DAY),
+ time_of_day: TimeOfDay::new(Self::DEFAULT_TIME),
+ }
+ }
+}
+
+#[derive(Clone)]
+pub struct DayOfWeek(u32);
+
+#[derive(Clone)]
+pub struct TimeOfDay(u32);
+
+impl DayOfWeek {
+ const DAYS: u32 = 7;
+
+ pub fn new(day: u32) -> Self {
+ Self(day % Self::DAYS)
+ }
+
+ pub fn value(&self) -> u32 {
+ self.0
+ }
+
+ pub fn next(&mut self) {
+ self.0 = (self.0 + 1) % Self::DAYS
+ }
+
+ pub fn fast_forward(&mut self, days: u32) {
+ self.0 = (self.0 + days) % Self::DAYS
+ }
+}
+
+impl TimeOfDay {
+ const TIME_PERIOD: u32 = 1440;
+
+ pub fn new(minutes: u32) -> Self {
+ Self(minutes % Self::TIME_PERIOD)
+ }
+
+ pub fn value(&self) -> u32 {
+ self.0
+ }
+
+ pub fn is_zero(&self) -> bool {
+ (self.0 % Self::TIME_PERIOD) == 0
+ }
+
+ pub fn tick(&mut self) -> bool {
+ self.0 = (self.0 + 1) % Self::TIME_PERIOD;
+ self.is_zero()
+ }
+
+ pub fn fast_forward(&mut self, minutes: u32) -> u32 {
+ self.0 += minutes;
+
+ let days_passed = self.0 / Self::TIME_PERIOD;
+ self.0 %= Self::TIME_PERIOD;
+
+ days_passed
+ }
+}
diff --git a/nap_gameserver/src/main.rs b/nap_gameserver/src/main.rs
new file mode 100644
index 0000000..896e619
--- /dev/null
+++ b/nap_gameserver/src/main.rs
@@ -0,0 +1,45 @@
+use std::{error::Error, sync::Arc};
+
+use common::{init_tracing, splash, util::load_or_create_config};
+use config::NapGSConfig;
+use data::init_data;
+use logic::player::PlayerManager;
+use net::NetSessionManager;
+
+mod config;
+mod database;
+mod handlers;
+mod logic;
+mod net;
+
+pub struct ServerState {
+ pub session_mgr: NetSessionManager,
+ pub player_mgr: PlayerManager,
+ pub config: NapGSConfig,
+}
+
+#[tokio::main]
+async fn main() -> Result<(), Box> {
+ splash::print("GameServer");
+ init_tracing();
+ tracing::info!("don't forget to visit https://discord.xeondev.com/");
+
+ let config = load_or_create_config::("nap_gameserver.toml");
+ init_data(&config.assets).expect("failed to init data");
+
+ let pg_pool = match common::database::init(&config.database_credentials).await {
+ Ok(pool) => pool,
+ Err(err) => {
+ tracing::error!("failed to connect to database: {err}");
+ std::process::exit(1);
+ }
+ };
+
+ let state = ServerState {
+ session_mgr: NetSessionManager::new(),
+ player_mgr: PlayerManager::new(pg_pool),
+ config,
+ };
+
+ net::listen(Arc::new(state)).await
+}
diff --git a/nap_gameserver/src/net/mod.rs b/nap_gameserver/src/net/mod.rs
new file mode 100644
index 0000000..64e3a92
--- /dev/null
+++ b/nap_gameserver/src/net/mod.rs
@@ -0,0 +1,9 @@
+mod packet;
+mod session;
+mod session_mgr;
+mod tcp_gateway;
+
+pub use packet::NetPacket;
+pub use session::{NetSession, NetSessionState};
+pub use session_mgr::NetSessionManager;
+pub use tcp_gateway::listen;
diff --git a/nap_gameserver/src/net/packet.rs b/nap_gameserver/src/net/packet.rs
new file mode 100644
index 0000000..bb76908
--- /dev/null
+++ b/nap_gameserver/src/net/packet.rs
@@ -0,0 +1,71 @@
+use prost::Message;
+use proto::PacketHead;
+use thiserror::Error;
+use tokio::io::{AsyncRead, AsyncReadExt};
+
+const HEAD_MAGIC: u32 = 0x01234567;
+const TAIL_MAGIC: u32 = 0x89ABCDEF;
+
+pub struct NetPacket {
+ pub cmd_id: u16,
+ pub head: PacketHead,
+ pub body: Box<[u8]>,
+}
+
+#[derive(Error, Debug)]
+pub enum DecodeError {
+ #[error("I/O error: {0}")]
+ IoError(#[from] std::io::Error),
+ #[error("head magic mismatch! expected: {HEAD_MAGIC}, got: {0}")]
+ HeadMagicMismatch(u32),
+ #[error("tail magic mismatch! expected: {TAIL_MAGIC}, got: {0}")]
+ TailMagicMismatch(u32),
+ #[error("failed to decode PacketHead: {0}")]
+ PacketHeadDecodeError(#[from] prost::DecodeError),
+}
+
+impl NetPacket {
+ pub async fn read(r: &mut R) -> Result
+ where
+ R: AsyncRead + Send + Unpin,
+ {
+ let head_magic = r.read_u32().await?;
+ matches!(head_magic, HEAD_MAGIC)
+ .then_some(())
+ .ok_or(DecodeError::HeadMagicMismatch(head_magic))?;
+
+ let cmd_id = r.read_u16().await?;
+ let head_len = r.read_u16().await? as usize;
+ let body_len = r.read_u32().await? as usize;
+
+ let mut head = vec![0u8; head_len];
+ r.read_exact(&mut head).await?;
+
+ let mut body = vec![0u8; body_len].into_boxed_slice();
+ r.read_exact(&mut body).await?;
+
+ let tail_magic = r.read_u32().await?;
+ matches!(tail_magic, TAIL_MAGIC)
+ .then_some(())
+ .ok_or(DecodeError::TailMagicMismatch(tail_magic))?;
+
+ let head = PacketHead::decode(&*head)?;
+
+ Ok(Self { cmd_id, head, body })
+ }
+
+ pub fn encode(&self) -> Vec {
+ let head = self.head.encode_to_vec();
+ let mut out = Vec::with_capacity(16 + head.len() + self.body.len());
+
+ out.extend(HEAD_MAGIC.to_be_bytes());
+ out.extend(self.cmd_id.to_be_bytes());
+ out.extend((head.len() as u16).to_be_bytes());
+ out.extend((self.body.len() as u32).to_be_bytes());
+ out.extend(head);
+ out.extend(&self.body);
+ out.extend(TAIL_MAGIC.to_be_bytes());
+
+ out
+ }
+}
diff --git a/nap_gameserver/src/net/session.rs b/nap_gameserver/src/net/session.rs
new file mode 100644
index 0000000..a702aff
--- /dev/null
+++ b/nap_gameserver/src/net/session.rs
@@ -0,0 +1,247 @@
+use std::sync::{atomic::AtomicU32, Arc, LazyLock};
+use thiserror::Error;
+
+use byteorder::{BE, LE};
+use common::{
+ cryptography::{Ec2b, MhyXorpad},
+ util,
+};
+use proto::{CmdID, NapMessage, PacketHead};
+use tokio::{
+ io::AsyncWriteExt,
+ net::TcpStream,
+ sync::{Mutex, MutexGuard, OnceCell},
+};
+
+use crate::{
+ handlers::{self, PacketHandlingError},
+ ServerState,
+};
+
+use super::packet::DecodeError;
+use super::NetPacket;
+
+static SECRET_KEY: LazyLock = LazyLock::new(|| {
+ let ec2b = Ec2b::read(&mut util::open_secret_key().expect("Failed to open secret key file"))
+ .expect("Failed to read Ec2b data");
+
+ MhyXorpad::new::(ec2b.derive_seed())
+});
+
+pub struct NetSession {
+ id: u64,
+ stream: Mutex,
+ session_key: OnceCell,
+ packet_id_counter: AtomicU32,
+ state: AtomicNetSessionState,
+ account_uid: OnceCell,
+ player_uid: OnceCell,
+}
+
+#[atomic_enum::atomic_enum]
+#[derive(PartialEq, Eq, PartialOrd)]
+pub enum NetSessionState {
+ StartEnterGameWorld,
+ PlayerGetTokenCsReq,
+ PlayerGetTokenScRsp,
+ PlayerLoginCsReq,
+ PlayerLoginScRsp,
+ StartBasicsReq,
+ EndBasicsReq,
+ EnterWorldScRsp,
+}
+
+impl NetSessionState {
+ pub fn is_command_allowed(&self, cmd_id: u16) -> bool {
+ match cmd_id {
+ proto::PlayerGetTokenCsReq::CMD_ID => *self == NetSessionState::StartEnterGameWorld,
+ proto::PlayerLoginCsReq::CMD_ID => *self == NetSessionState::PlayerGetTokenScRsp,
+ _ => *self >= NetSessionState::StartBasicsReq,
+ }
+ }
+
+ pub fn is_auth(&self) -> bool {
+ *self < NetSessionState::PlayerLoginScRsp
+ }
+}
+
+#[derive(Error, Debug)]
+pub enum SessionError {
+ #[error("NetPacket decode failed: {0}")]
+ PacketDecode(#[from] DecodeError),
+ #[error("failed to handle packet: {0}")]
+ PacketHandling(#[from] PacketHandlingError),
+}
+
+impl NetSession {
+ pub fn new(id: u64, stream: TcpStream) -> Self {
+ Self {
+ id,
+ stream: Mutex::new(stream),
+ session_key: OnceCell::new(),
+ packet_id_counter: AtomicU32::new(0),
+ state: AtomicNetSessionState::new(NetSessionState::StartEnterGameWorld),
+ account_uid: OnceCell::new(),
+ player_uid: OnceCell::new(),
+ }
+ }
+
+ pub async fn run(&self, state: Arc) -> Result<(), SessionError> {
+ let mut last_save_time = util::cur_timestamp();
+
+ let result = loop {
+ let packet = match NetPacket::read(&mut *self.stream().await).await {
+ Ok(packet) => packet,
+ Err(DecodeError::IoError(_)) => break Ok(()),
+ Err(err) => break Err(SessionError::PacketDecode(err)),
+ };
+
+ match self.handle_packet(packet, &state).await {
+ Ok(()) => (),
+ Err(PacketHandlingError::Logout) => break Ok(()),
+ Err(err) => break Err(SessionError::PacketHandling(err)),
+ }
+
+ if let Some(uid) = self.player_uid.get() {
+ if (util::cur_timestamp() - last_save_time)
+ >= state.config.player_save_period_seconds
+ {
+ state.player_mgr.save(*uid).await;
+ last_save_time = util::cur_timestamp();
+ }
+ }
+ };
+
+ self.on_disconnect(&state).await;
+ result
+ }
+
+ async fn handle_packet(
+ &self,
+ mut packet: NetPacket,
+ state: &ServerState,
+ ) -> Result<(), PacketHandlingError> {
+ self.xor_payload(packet.cmd_id, &mut packet.body);
+ let net_state = self.state.load(std::sync::atomic::Ordering::SeqCst);
+
+ if !net_state.is_command_allowed(packet.cmd_id) {
+ tracing::warn!(
+ "received cmd_id ({}) is not allowed in current state ({:?})",
+ packet.cmd_id,
+ self.state.load(std::sync::atomic::Ordering::SeqCst)
+ );
+ } else if net_state.is_auth() {
+ if !handlers::handle_auth_request(self, &packet, state).await? {
+ tracing::warn!(
+ "[LOGIN] packet with cmd_id={} wasn't handled, body: {}",
+ packet.cmd_id,
+ hex::encode(&packet.body)
+ );
+ }
+ } else if !handlers::handle_request(self, &packet, state).await? {
+ if !handlers::handle_notify(self, &packet, state).await? {
+ tracing::warn!(
+ "packet with cmd_id={} wasn't handled, body: {}",
+ packet.cmd_id,
+ hex::encode(&packet.body)
+ );
+ }
+ }
+
+ Ok(())
+ }
+
+ async fn on_disconnect(&self, state: &ServerState) {
+ state.session_mgr.remove(self.id);
+ if let Some(player_uid) = self.player_uid.get() {
+ state.player_mgr.save_and_remove(*player_uid).await;
+ }
+ }
+
+ pub async fn notify(&self, mut ntf: impl NapMessage) -> Result<(), std::io::Error> {
+ ntf.xor_fields();
+
+ self.send(NetPacket {
+ cmd_id: ntf.get_cmd_id(),
+ head: PacketHead {
+ packet_id: self.next_packet_id(),
+ ..Default::default()
+ },
+ body: ntf.encode_to_vec().into_boxed_slice(),
+ })
+ .await
+ }
+
+ pub async fn send_rsp(
+ &self,
+ request_id: u32,
+ mut rsp: impl NapMessage,
+ ) -> Result<(), std::io::Error> {
+ rsp.xor_fields();
+
+ self.send(NetPacket {
+ cmd_id: rsp.get_cmd_id(),
+ head: PacketHead {
+ packet_id: self.next_packet_id(),
+ request_id,
+ ..Default::default()
+ },
+ body: rsp.encode_to_vec().into_boxed_slice(),
+ })
+ .await
+ }
+
+ async fn send(&self, mut packet: NetPacket) -> Result<(), std::io::Error> {
+ self.xor_payload(packet.cmd_id, &mut packet.body);
+
+ let buf = packet.encode();
+ self.stream().await.write_all(&buf).await
+ }
+
+ async fn stream(&self) -> MutexGuard<'_, TcpStream> {
+ self.stream.lock().await
+ }
+
+ pub fn id(&self) -> u64 {
+ self.id
+ }
+
+ pub fn set_session_key(&self, seed: u64) {
+ let _ = self.session_key.set(MhyXorpad::new::(seed));
+ }
+
+ pub fn account_uid(&self) -> Option<&String> {
+ self.account_uid.get()
+ }
+
+ pub fn set_account_uid(&self, uid: String) -> bool {
+ self.account_uid.set(uid).is_ok()
+ }
+
+ pub fn player_uid(&self) -> Option<&u32> {
+ self.player_uid.get()
+ }
+
+ pub fn set_player_uid(&self, uid: u32) -> bool {
+ self.player_uid.set(uid).is_ok()
+ }
+
+ fn xor_payload(&self, cmd_id: u16, buf: &mut [u8]) {
+ let key = match self.session_key.get() {
+ _ if cmd_id == proto::PlayerGetTokenScRsp::CMD_ID => &*SECRET_KEY,
+ Some(key) => key,
+ None => &*SECRET_KEY,
+ };
+
+ key.xor(buf);
+ }
+
+ fn next_packet_id(&self) -> u32 {
+ self.packet_id_counter
+ .fetch_add(1, std::sync::atomic::Ordering::SeqCst)
+ }
+
+ pub fn set_state(&self, state: NetSessionState) {
+ self.state.store(state, std::sync::atomic::Ordering::SeqCst);
+ }
+}
diff --git a/nap_gameserver/src/net/session_mgr.rs b/nap_gameserver/src/net/session_mgr.rs
new file mode 100644
index 0000000..bb32c8c
--- /dev/null
+++ b/nap_gameserver/src/net/session_mgr.rs
@@ -0,0 +1,38 @@
+use super::NetSession;
+use std::sync::{
+ atomic::{AtomicU64, Ordering},
+ Arc,
+};
+
+use dashmap::DashMap;
+use tokio::net::TcpStream;
+
+pub struct NetSessionManager {
+ sessions: DashMap>,
+ id_counter: AtomicU64,
+}
+
+impl NetSessionManager {
+ pub fn new() -> Self {
+ Self {
+ sessions: DashMap::new(),
+ id_counter: AtomicU64::new(1),
+ }
+ }
+
+ pub fn create(&self, stream: TcpStream) -> Arc {
+ let id = self.id_counter.fetch_add(1, Ordering::SeqCst);
+ let session = Arc::new(NetSession::new(id, stream));
+ self.sessions.insert(id, session.clone());
+
+ session
+ }
+
+ pub fn get(&self, id: u64) -> Option> {
+ self.sessions.get(&id).map(|s| (*s).clone())
+ }
+
+ pub fn remove(&self, id: u64) {
+ self.sessions.remove(&id);
+ }
+}
diff --git a/nap_gameserver/src/net/tcp_gateway.rs b/nap_gameserver/src/net/tcp_gateway.rs
new file mode 100644
index 0000000..423df75
--- /dev/null
+++ b/nap_gameserver/src/net/tcp_gateway.rs
@@ -0,0 +1,31 @@
+use std::{error::Error, sync::Arc};
+
+use tokio::net::TcpListener;
+
+use crate::ServerState;
+
+pub async fn listen(state: Arc) -> Result<(), Box> {
+ let bind_addr = &state.config.tcp_listen_addr;
+
+ let listener = TcpListener::bind(bind_addr).await?;
+ tracing::info!("listening at {bind_addr}");
+
+ loop {
+ let Ok((stream, addr)) = listener.accept().await else {
+ continue;
+ };
+
+ tracing::info!("new connection from {addr}");
+ let session = state.session_mgr.create(stream);
+
+ let state = state.clone();
+ tokio::spawn(async move {
+ match session.run(state).await {
+ Ok(()) => tracing::info!("session from {addr} disconnected"),
+ Err(err) => {
+ tracing::error!("error occurred: {err}, session from {addr} disconnected!");
+ }
+ }
+ });
+ }
+}
diff --git a/nap_proto/Cargo.toml b/nap_proto/Cargo.toml
new file mode 100644
index 0000000..1f896ad
--- /dev/null
+++ b/nap_proto/Cargo.toml
@@ -0,0 +1,12 @@
+[package]
+name = "proto"
+edition = "2021"
+version.workspace = true
+
+[dependencies]
+prost.workspace = true
+prost-types.workspace = true
+proto_gen.workspace = true
+
+[build-dependencies]
+prost-build.workspace = true
diff --git a/nap_proto/build.rs b/nap_proto/build.rs
new file mode 100644
index 0000000..cc42e17
--- /dev/null
+++ b/nap_proto/build.rs
@@ -0,0 +1,68 @@
+use std::{
+ fs::{self, File},
+ io::{BufRead, BufReader},
+ path::Path,
+};
+
+pub fn main() {
+ let proto_file = "nap.proto";
+ if Path::new(&proto_file).exists() {
+ println!("cargo:rerun-if-changed={proto_file}");
+ let _ = fs::create_dir("out/");
+
+ prost_build::Config::new()
+ .out_dir("out/")
+ .type_attribute(".", "#[derive(proto_gen::CmdID)]")
+ .type_attribute(".", "#[derive(proto_gen::XorFields)]")
+ .compile_protos(&[proto_file], &["."])
+ .unwrap();
+ apply_xor(Path::new("out/_.rs")).unwrap();
+ }
+
+ let proto_file = "bin.server.proto";
+ if Path::new(&proto_file).exists() {
+ println!("cargo:rerun-if-changed={proto_file}");
+ let _ = fs::create_dir("out/");
+
+ prost_build::Config::new()
+ .out_dir("out/")
+ .compile_protos(&[proto_file], &["bin"])
+ .unwrap();
+ }
+}
+
+fn apply_xor(path: &Path) -> std::io::Result<()> {
+ let file = File::open(path)?;
+ let reader = BufReader::new(file);
+ let mut output = Vec::new();
+
+ let mut cmd_id_attr = None;
+ for line in reader.lines() {
+ let line = line?;
+ if line.contains("xor const: ") {
+ if !line.contains("xor const: 0") {
+ output.push(make_xor_attr(&line).unwrap());
+ }
+ } else if line.contains("CmdID: ") {
+ cmd_id_attr = Some(make_cmd_id_attr(&line).unwrap());
+ } else {
+ output.push(line);
+ if let Some(attr) = cmd_id_attr.take() {
+ output.push(attr);
+ }
+ }
+ }
+
+ fs::write(path, output.join("\n").as_bytes())?;
+ Ok(())
+}
+
+fn make_xor_attr(line: &str) -> Option {
+ let xor_value = line.split("xor const: ").nth(1)?.parse::().ok()?;
+ Some(format!(" #[xor({xor_value})]"))
+}
+
+fn make_cmd_id_attr(line: &str) -> Option {
+ let cmd_id = line.split("CmdID: ").nth(1)?.parse::().ok()?;
+ Some(format!("#[cmdid({cmd_id})]"))
+}
diff --git a/nap_proto/out/_.rs b/nap_proto/out/_.rs
new file mode 100644
index 0000000..32f5545
--- /dev/null
+++ b/nap_proto/out/_.rs
@@ -0,0 +1,60348 @@
+// This file is @generated by prost-build.
+#[derive(proto_gen::CmdID)]
+#[cmdid(1340)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Gmeephnlneg {
+ #[xor(9536)]
+ #[prost(uint32, tag = "12")]
+ pub iodbjkkegoc: u32,
+ #[prost(bool, tag = "15")]
+ pub hbjekhglkho: bool,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Kkdbkodlipi {
+ #[xor(7294)]
+ #[prost(int32, tag = "5")]
+ pub blpbniognen: i32,
+ #[prost(message, repeated, tag = "1")]
+ pub ohphimabale: ::prost::alloc::vec::Vec,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(498)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Kkgabophogk {
+ #[prost(bool, tag = "13")]
+ pub dachboigobc: bool,
+ #[prost(message, optional, tag = "6")]
+ pub battle_result: ::core::option::Option,
+ #[xor(5186)]
+ #[prost(int64, tag = "3")]
+ pub battle_uid: i64,
+ #[xor(13544)]
+ #[prost(int32, tag = "14")]
+ pub battle_id: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct AbyssDutyData {
+ #[xor(6206)]
+ #[prost(uint32, tag = "9")]
+ pub kjoopbmjegm: u32,
+ #[prost(map = "uint32, uint32", tag = "6")]
+ pub finish_condition_progress: ::std::collections::HashMap,
+ #[xor(14159)]
+ #[prost(uint32, tag = "1")]
+ pub ahpalhhnkdc: u32,
+ #[xor(963)]
+ #[prost(uint32, tag = "2")]
+ pub template_id: u32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Ngnlpinkeeo {
+ #[prost(message, optional, tag = "1")]
+ pub gkehhhaeffa: ::core::option::Option,
+ #[prost(message, optional, tag = "2")]
+ pub mdnhahnfmfl: ::core::option::Option,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Bndpnbjnicc {
+ #[prost(string, tag = "1")]
+ pub mcmkaiinihb: ::prost::alloc::string::String,
+ #[prost(string, tag = "2")]
+ pub oeakkkamdlg: ::prost::alloc::string::String,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Cjdgecfpbnb {}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Gelcdeemien {
+ #[prost(string, tag = "1")]
+ pub dldkebnaemc: ::prost::alloc::string::String,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(718)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Bhoildhkhpj {
+ #[prost(uint32, repeated, tag = "10")]
+ pub mnojlnoblcl: ::prost::alloc::vec::Vec,
+ #[prost(uint32, repeated, tag = "2")]
+ pub kfhpbnnkidh: ::prost::alloc::vec::Vec,
+ #[xor(3551)]
+ #[prost(int32, tag = "6")]
+ pub retcode: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Jgapkmjbomc {
+ #[prost(message, optional, tag = "1")]
+ pub dgdplpmddec: ::core::option::Option,
+ #[prost(int32, tag = "2")]
+ pub eckdphgbknh: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(316)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Kngifdpoiae {}
+#[derive(proto_gen::CmdID)]
+#[cmdid(632)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Ekciolgenkp {
+ #[xor(5355)]
+ #[prost(int32, tag = "15")]
+ pub retcode: i32,
+ #[xor(8354)]
+ #[prost(uint32, tag = "7")]
+ pub elamhfhmooa: u32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Hagpnckfcdh {
+ #[prost(uint32, repeated, tag = "1")]
+ pub jcjehbmmief: ::prost::alloc::vec::Vec,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Ckoiijechbm {
+ #[prost(enumeration = "Ckliokcobmc", tag = "1")]
+ pub fhlcnolpfml: i32,
+ #[prost(string, tag = "2")]
+ pub moncfdmpofj: ::prost::alloc::string::String,
+ #[prost(string, tag = "3")]
+ pub oaclhaabola: ::prost::alloc::string::String,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(658)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Ghgacdlmpae {
+ #[prost(uint32, repeated, tag = "3")]
+ pub hmfkjheaanh: ::prost::alloc::vec::Vec,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Aekcbijoaaf {
+ #[prost(bool, tag = "9")]
+ pub plmiiofhhaj: bool,
+ #[xor(1458)]
+ #[prost(int32, tag = "12")]
+ pub fbmolobblge: i32,
+ #[xor(4831)]
+ #[prost(int32, tag = "1")]
+ pub num: i32,
+ #[prost(float, tag = "10")]
+ pub mkjndiapleb: f32,
+ #[prost(float, tag = "4")]
+ pub fboelpmooig: f32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Baohjfcokij {
+ #[prost(string, tag = "1")]
+ pub nadbbnnlcco: ::prost::alloc::string::String,
+ #[prost(message, optional, tag = "2")]
+ pub item_id: ::core::option::Option,
+ #[prost(uint32, tag = "3")]
+ pub bedcpoehdkc: u32,
+ #[prost(message, repeated, tag = "4")]
+ pub predicates: ::prost::alloc::vec::Vec,
+ #[prost(uint32, repeated, tag = "5")]
+ pub omdaohnmedj: ::prost::alloc::vec::Vec,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Dgmdnbjaaem {}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Nkhnlakggmj {
+ #[xor(686)]
+ #[prost(uint32, tag = "11")]
+ pub dehkpnocdjg: u32,
+ #[prost(map = "uint32, uint32", tag = "6")]
+ pub finish_condition_progress: ::std::collections::HashMap,
+ #[prost(string, tag = "7")]
+ pub gpdjjkogccm: ::prost::alloc::string::String,
+ #[xor(5888)]
+ #[prost(uint32, tag = "13")]
+ pub ficaggelnpc: u32,
+ #[xor(5542)]
+ #[prost(uint32, tag = "10")]
+ pub template_id: u32,
+ #[prost(enumeration = "Cmmembfifpk", tag = "4")]
+ pub ofolagfmcmo: i32,
+ #[xor(11347)]
+ #[prost(uint32, tag = "2")]
+ pub mkobghhgobc: u32,
+ #[prost(string, tag = "1")]
+ pub iddehlcpjjn: ::prost::alloc::string::String,
+ #[xor(10163)]
+ #[prost(int64, tag = "14")]
+ pub phkcdmjheen: i64,
+ #[xor(8852)]
+ #[prost(uint32, tag = "8")]
+ pub ppnbkmndpjc: u32,
+ #[xor(13996)]
+ #[prost(uint32, tag = "5")]
+ pub bcimengnibi: u32,
+ #[prost(string, tag = "3")]
+ pub title: ::prost::alloc::string::String,
+ #[prost(enumeration = "Cccoaoekaif", tag = "15")]
+ pub lmiamoihnid: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Lcnicjccpde {
+ #[prost(int32, repeated, tag = "13")]
+ pub unlock_id_list: ::prost::alloc::vec::Vec,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(1396)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Iojadicmfnl {
+ #[prost(enumeration = "Fljplglhfin", tag = "14")]
+ pub agjbemefhej: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Eoiakcmjoha {
+ #[prost(int32, tag = "1")]
+ pub fjcflipfpmo: i32,
+ #[prost(int32, tag = "2")]
+ pub lmpkbfofine: i32,
+ #[prost(int32, tag = "3")]
+ pub gnibbcpoeci: i32,
+ #[prost(int32, tag = "4")]
+ pub hengbhlpbab: i32,
+ #[prost(int32, tag = "5")]
+ pub geefpgnnkbc: i32,
+ #[prost(int32, tag = "6")]
+ pub hoaicgkhjlm: i32,
+ #[prost(int32, tag = "7")]
+ pub nbfbkbjencf: i32,
+ #[prost(int32, tag = "8")]
+ pub pdjdgdpcndb: i32,
+ #[prost(int32, tag = "9")]
+ pub ccdjelebepg: i32,
+ #[prost(int32, tag = "10")]
+ pub oaiglkjpdhp: i32,
+ #[prost(int32, tag = "11")]
+ pub kaenmifjobl: i32,
+ #[prost(int32, tag = "12")]
+ pub ochgjoaican: i32,
+ #[prost(int32, tag = "13")]
+ pub cbfkobbncpo: i32,
+ #[prost(int32, tag = "14")]
+ pub nnpkhadhili: i32,
+ #[prost(int32, tag = "15")]
+ pub aplnfojjgol: i32,
+ #[prost(int32, tag = "16")]
+ pub gdinonpbgnj: i32,
+ #[prost(int32, tag = "17")]
+ pub mkfiaffgpmb: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Ekgkbchmdfg {
+ #[prost(int32, tag = "1")]
+ pub abhafocgjgp: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Dcngcjnkmno {
+ #[xor(15835)]
+ #[prost(int32, tag = "7")]
+ pub hgejomichaj: i32,
+ #[xor(189)]
+ #[prost(int32, tag = "4")]
+ pub ofllefihnlp: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(604)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Haiehnolemd {
+ #[xor(8076)]
+ #[prost(int32, tag = "14")]
+ pub retcode: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Ockkmgggbld {
+ #[prost(enumeration = "ChessUiControlType", tag = "7")]
+ pub knjdlppjnjp: i32,
+ #[xor(14357)]
+ #[prost(int32, tag = "1")]
+ pub num: i32,
+ #[prost(enumeration = "ChessUiIconType", tag = "9")]
+ pub obeigedladh: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Hpalfgllgje {
+ #[xor(990)]
+ #[prost(uint32, tag = "5")]
+ pub avatar_id: u32,
+ #[xor(13824)]
+ #[prost(uint32, tag = "4")]
+ pub item_id: u32,
+ #[xor(6669)]
+ #[prost(uint32, tag = "1")]
+ pub num: u32,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(5164)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Pijchhdicik {
+ #[prost(message, repeated, tag = "11")]
+ pub mafcgflkhic: ::prost::alloc::vec::Vec,
+ #[xor(14063)]
+ #[prost(uint64, tag = "5")]
+ pub dkmbmkcdepe: u64,
+ #[prost(message, optional, tag = "3")]
+ pub info: ::core::option::Option,
+ #[xor(9976)]
+ #[prost(uint64, tag = "2")]
+ pub jmnpooedngh: u64,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(1080)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Plfbkmmmdbm {
+ #[prost(map = "uint32, int32", tag = "15")]
+ pub nknnphiofnc: ::std::collections::HashMap,
+ #[xor(10983)]
+ #[prost(uint32, tag = "7")]
+ pub num: u32,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(612)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Gofdhmfmbij {
+ #[xor(3542)]
+ #[prost(int32, tag = "12")]
+ pub retcode: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Lccpbndiccj {
+ #[prost(message, optional, tag = "8")]
+ pub begdklfbmip: ::core::option::Option,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Cejpodgpgol {
+ #[prost(message, optional, tag = "1")]
+ pub phcdebbpbic: ::core::option::Option,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Ckmnhgppnlh {
+ #[prost(uint32, tag = "1")]
+ pub fjochpjpckk: u32,
+ #[prost(uint32, tag = "2")]
+ pub ipenajdpamc: u32,
+ #[prost(uint32, tag = "3")]
+ pub pjemhopkpao: u32,
+ #[prost(enumeration = "Iejffobjgpg", tag = "4")]
+ pub hcojlnaaidc: i32,
+ #[prost(uint32, repeated, tag = "5")]
+ pub kkdhnljdgcj: ::prost::alloc::vec::Vec,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Ckkenmdndie {
+ #[prost(uint32, tag = "1")]
+ pub uid: u32,
+ #[prost(uint32, tag = "2")]
+ pub rank: u32,
+ #[prost(uint32, tag = "3")]
+ pub score: u32,
+ #[prost(message, optional, tag = "4")]
+ pub efegdgbgjdj: ::core::option::Option,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Ebjndhaabhd {}
+#[derive(proto_gen::CmdID)]
+#[cmdid(641)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Bpjgcjfagjn {
+ #[xor(10421)]
+ #[prost(int32, tag = "12")]
+ pub retcode: i32,
+ #[xor(5495)]
+ #[prost(uint32, tag = "3")]
+ pub quest_id: u32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Fbdfodnidlh {
+ #[prost(message, optional, tag = "1")]
+ pub quest_id: ::core::option::Option,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Licedgflldk {
+ #[xor(5821)]
+ #[prost(uint32, tag = "4")]
+ pub avatar_id: u32,
+ #[xor(14563)]
+ #[prost(uint32, tag = "1")]
+ pub damage: u32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Aooldhifkbd {
+ #[xor(1391)]
+ #[prost(int32, tag = "7")]
+ pub retcode: i32,
+ #[prost(message, repeated, tag = "3")]
+ pub fjhcnbiecjl: ::prost::alloc::vec::Vec,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Mnhbpdcpmln {
+ #[xor(4090)]
+ #[prost(int32, tag = "5")]
+ pub ibmecicmfki: i32,
+ #[xor(10072)]
+ #[prost(int32, tag = "7")]
+ pub hfgdfahknam: i32,
+ #[xor(4138)]
+ #[prost(int32, tag = "8")]
+ pub hhnmgamihmn: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Eeoeklodgid {}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Feecjgonjfm {
+ #[prost(message, repeated, tag = "12")]
+ pub bhenhlnmjoi: ::prost::alloc::vec::Vec,
+ #[prost(uint32, repeated, tag = "15")]
+ pub coffepbhbaa: ::prost::alloc::vec::Vec,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Ioicimpnbhm {
+ #[prost(message, optional, tag = "11")]
+ pub ebhhlpjehid: ::core::option::Option,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Dhehemaohfd {
+ #[prost(int32, tag = "1")]
+ pub miecobaddhc: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct LogTrapInfo {
+ #[prost(int32, tag = "1")]
+ pub trap_id: i32,
+ #[prost(int64, tag = "2")]
+ pub trap_uid: i64,
+ #[prost(int32, tag = "3")]
+ pub damage: i32,
+ #[prost(int32, tag = "4")]
+ pub live_time: i32,
+ #[prost(int32, tag = "5")]
+ pub is_trigger: i32,
+ #[prost(int32, tag = "6")]
+ pub imcmgiijhfb: i32,
+ #[prost(int32, tag = "7")]
+ pub mfececnkdce: i32,
+ #[prost(int32, tag = "8")]
+ pub enbglllhcfd: i32,
+ #[prost(int32, tag = "9")]
+ pub alllcjnlamc: i32,
+ #[prost(int32, tag = "10")]
+ pub mdcepdgblck: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Aoddoghjgef {
+ #[prost(string, repeated, tag = "1")]
+ pub jgdbedcacpp: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Iggbdkbgphj {
+ #[prost(message, repeated, tag = "10")]
+ pub kbinkakmmcl: ::prost::alloc::vec::Vec,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Jlbbfncemhl {
+ #[prost(uint32, tag = "1")]
+ pub jkanfkbccpp: u32,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(2018)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Bobidaafgje {
+ #[xor(2738)]
+ #[prost(uint32, tag = "8")]
+ pub level: u32,
+ #[xor(13078)]
+ #[prost(uint32, tag = "3")]
+ pub dbehgfkggpk: u32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Bajhdbfeckp {
+ #[prost(message, optional, tag = "1")]
+ pub section_id: ::core::option::Option,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Jeekolclhed {
+ #[prost(enumeration = "VariableScope", tag = "1")]
+ pub fcdpekomndm: i32,
+ #[prost(string, tag = "2")]
+ pub eabhecadfgl: ::prost::alloc::string::String,
+ #[prost(enumeration = "TypeOfSetList", tag = "3")]
+ pub ojhhpklhdjg: i32,
+ #[prost(message, repeated, tag = "4")]
+ pub odecaelpjho: ::prost::alloc::vec::Vec,
+ #[prost(map = "string, message", tag = "5")]
+ pub igjcaafeajk: ::std::collections::HashMap<
+ ::prost::alloc::string::String,
+ StringEntry,
+ >,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Obncggnjhle {
+ #[xor(2982)]
+ #[prost(uint32, tag = "2")]
+ pub ijoecccdadi: u32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Agafajmncio {
+ #[prost(enumeration = "Nnjpojfcbpk", tag = "1")]
+ pub pnnhdkcfeeb: i32,
+ #[prost(enumeration = "Njmgdnmdpcd", tag = "4")]
+ pub pfkbhinphki: i32,
+ #[prost(message, optional, tag = "6")]
+ pub mafdkbbjomk: ::core::option::Option,
+ #[prost(enumeration = "Eibhenfckie", tag = "8")]
+ pub lpbhklngmnk: i32,
+ #[prost(message, optional, tag = "13")]
+ pub chmfafeaaec: ::core::option::Option,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(877)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Clmolehfkil {
+ #[xor(10891)]
+ #[prost(int32, tag = "3")]
+ pub bojkongkemd: i32,
+ #[prost(message, repeated, tag = "4")]
+ pub okiccbjkkoj: ::prost::alloc::vec::Vec,
+ #[xor(1757)]
+ #[prost(int32, tag = "9")]
+ pub retcode: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Pkmpgegjnaa {
+ #[prost(bool, tag = "1")]
+ pub gcbccdlhjfd: bool,
+ #[prost(bool, tag = "2")]
+ pub dnpbgfmbbpa: bool,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(3209)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Gollkenbeof {
+ #[xor(11487)]
+ #[prost(int32, tag = "12")]
+ pub retcode: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(5123)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Ekhjgeikgba {
+ #[xor(10428)]
+ #[prost(uint64, tag = "15")]
+ pub jmnpooedngh: u64,
+ #[prost(message, repeated, tag = "12")]
+ pub mafcgflkhic: ::prost::alloc::vec::Vec,
+ #[prost(message, optional, tag = "11")]
+ pub info: ::core::option::Option,
+ #[xor(10147)]
+ #[prost(uint64, tag = "8")]
+ pub dkmbmkcdepe: u64,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Fbjfmflmlca {
+ #[prost(int32, tag = "1")]
+ pub cmacbfkaoma: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Dofkpomcepc {}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Aahgcnhamoj {
+ #[prost(uint64, repeated, tag = "14")]
+ pub cbgjohgniip: ::prost::alloc::vec::Vec,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Ldbhmpnnicl {
+ #[prost(bool, tag = "1")]
+ pub ifeeilniaol: bool,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(2965)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Ibcibmadlof {
+ #[xor(10603)]
+ #[prost(int32, tag = "15")]
+ pub retcode: i32,
+ #[prost(message, optional, tag = "10")]
+ pub jamlmbokncg: ::core::option::Option,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Hpoimmjhich {
+ #[prost(message, optional, tag = "1")]
+ pub cbgeodkpcfa: ::core::option::Option,
+ #[prost(enumeration = "VariableScope", tag = "2")]
+ pub fcdpekomndm: i32,
+ #[prost(message, optional, tag = "3")]
+ pub boigcdofhii: ::core::option::Option,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(2257)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Acmdcinhdfe {
+ #[xor(14540)]
+ #[prost(int32, tag = "4")]
+ pub retcode: i32,
+ #[xor(15963)]
+ #[prost(uint32, tag = "3")]
+ pub ljjhakbfaim: u32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Ehabldkgceo {
+ #[prost(bool, tag = "1")]
+ pub fgmplnehagh: bool,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Fkkojjgepnb {
+ #[prost(string, tag = "4")]
+ pub hocgmcajaal: ::prost::alloc::string::String,
+ #[prost(uint32, repeated, tag = "1234")]
+ pub jhegkfffnho: ::prost::alloc::vec::Vec,
+ #[prost(bool, tag = "42")]
+ pub nddohlngkpj: bool,
+ #[prost(int32, repeated, tag = "425")]
+ pub cabobahmfoo: ::prost::alloc::vec::Vec,
+ #[xor(1278)]
+ #[prost(uint32, tag = "1268")]
+ pub hbakancpbkd: u32,
+ #[xor(7080)]
+ #[prost(uint32, tag = "788")]
+ pub nkikgkhhgho: u32,
+ #[prost(string, tag = "14")]
+ pub fdambhgpjab: ::prost::alloc::string::String,
+ #[xor(10514)]
+ #[prost(uint32, tag = "679")]
+ pub mjiiknenehg: u32,
+ #[prost(bool, tag = "50")]
+ pub aobemkmdkgo: bool,
+ #[xor(11981)]
+ #[prost(int32, tag = "5")]
+ pub fphnongcfga: i32,
+ #[xor(9424)]
+ #[prost(uint32, tag = "15")]
+ pub aapgogjocgb: u32,
+ #[prost(uint32, repeated, tag = "732")]
+ pub jpipifpcihf: ::prost::alloc::vec::Vec,
+ #[xor(1659)]
+ #[prost(uint32, tag = "6")]
+ pub amhkclkeblh: u32,
+ #[prost(string, tag = "1233")]
+ pub mdcpginfopk: ::prost::alloc::string::String,
+ #[prost(bool, tag = "74")]
+ pub hmpjfcdnaeh: bool,
+ #[prost(string, tag = "1")]
+ pub ipenifeaflj: ::prost::alloc::string::String,
+ #[xor(11567)]
+ #[prost(uint32, tag = "8")]
+ pub cnomghadpof: u32,
+ #[xor(6029)]
+ #[prost(uint32, tag = "7")]
+ pub bdhckehljcc: u32,
+ #[xor(3244)]
+ #[prost(uint32, tag = "1625")]
+ pub lchdjcdjiik: u32,
+ #[xor(4851)]
+ #[prost(int64, tag = "3")]
+ pub phkcdmjheen: i64,
+ #[xor(8589)]
+ #[prost(int32, tag = "505")]
+ pub lecpejadije: i32,
+ #[xor(15310)]
+ #[prost(int64, tag = "13")]
+ pub start_timestamp: i64,
+ #[prost(string, tag = "11")]
+ pub clpbnooldog: ::prost::alloc::string::String,
+ #[prost(string, tag = "9")]
+ pub kaflnjilgmj: ::prost::alloc::string::String,
+ #[prost(string, tag = "743")]
+ pub eifopebmhfo: ::prost::alloc::string::String,
+ #[prost(string, tag = "655")]
+ pub ffffmcflfmb: ::prost::alloc::string::String,
+ #[prost(bool, tag = "295")]
+ pub fdmdbaoddom: bool,
+ #[xor(15648)]
+ #[prost(uint32, tag = "1510")]
+ pub ebgcalpgcah: u32,
+ #[prost(string, tag = "1163")]
+ pub pjpcdnfkkcn: ::prost::alloc::string::String,
+ #[prost(string, tag = "12")]
+ pub cnipfpbloal: ::prost::alloc::string::String,
+ #[xor(9382)]
+ #[prost(uint32, tag = "290")]
+ pub cmpghccljlf: u32,
+ #[xor(12031)]
+ #[prost(uint32, tag = "2")]
+ pub alciljacdod: u32,
+ #[xor(11766)]
+ #[prost(uint32, tag = "10")]
+ pub cmkiohccoil: u32,
+ #[xor(11451)]
+ #[prost(int64, tag = "1089")]
+ pub lohgoaeodof: i64,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Hegbodnhnom {
+ #[prost(message, optional, tag = "2")]
+ pub ehgaplnmnhi: ::core::option::Option,
+ #[prost(message, optional, tag = "3")]
+ pub bhpdodagglp: ::core::option::Option,
+ #[prost(message, optional, tag = "5")]
+ pub ekhmhoiffmp: ::core::option::Option,
+ #[prost(message, optional, tag = "8")]
+ pub facoccnpnhp: ::core::option::Option,
+ #[prost(message, optional, tag = "9")]
+ pub gdkiklmofjk: ::core::option::Option,
+ #[prost(message, optional, tag = "10")]
+ pub gjclmlaikbm: ::core::option::Option,
+ #[prost(message, optional, tag = "11")]
+ pub jdoinkjnehm: ::core::option::Option,
+ #[prost(message, optional, tag = "12")]
+ pub gepclhchljg: ::core::option::Option,
+ #[prost(message, optional, tag = "13")]
+ pub nbkigcdeifl: ::core::option::Option,
+ #[prost(message, optional, tag = "14")]
+ pub lmnioimegah: ::core::option::Option,
+ #[prost(message, optional, tag = "15")]
+ pub jpajmpoinko: ::core::option::Option,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(2027)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Dcgobhlfgei {
+ #[xor(12879)]
+ #[prost(uint32, tag = "12")]
+ pub quest_id: u32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Jmlcnhpajjd {
+ #[prost(message, repeated, tag = "1")]
+ pub hjmeodfekco: ::prost::alloc::vec::Vec,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(98)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct GetPlayerBasicInfoScRsp {
+ #[xor(9584)]
+ #[prost(int32, tag = "15")]
+ pub retcode: i32,
+ #[prost(message, optional, tag = "8")]
+ pub basic_info: ::core::option::Option,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Igieiojpkeh {
+ #[xor(9735)]
+ #[prost(int64, tag = "7")]
+ pub bamnancbmge: i64,
+ #[xor(1855)]
+ #[prost(int64, tag = "2")]
+ pub unlock_time: i64,
+ #[xor(5348)]
+ #[prost(uint32, tag = "4")]
+ pub template_id: u32,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(953)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Ijddomkbifa {
+ #[xor(15548)]
+ #[prost(int32, tag = "12")]
+ pub retcode: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Hlpdblepabc {
+ #[prost(int32, tag = "1")]
+ pub bedcpoehdkc: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(3299)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Aoealfpncbb {
+ #[xor(183)]
+ #[prost(uint32, tag = "15")]
+ pub ikgcckcpjdg: u32,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(606)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Nbjmdkdcpcg {
+ #[xor(3658)]
+ #[prost(int32, tag = "5")]
+ pub retcode: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Fkhbkjlkggf {
+ #[prost(enumeration = "HollowEntityType", tag = "1")]
+ pub okdogekihnp: i32,
+ #[prost(message, optional, tag = "2")]
+ pub mdnhahnfmfl: ::core::option::Option,
+ #[prost(message, optional, tag = "3")]
+ pub egdmlifeihf: ::core::option::Option,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Jbojkodhiag {
+ #[xor(6452)]
+ #[prost(int32, tag = "12")]
+ pub jmekicekjmn: i32,
+ #[xor(4810)]
+ #[prost(int32, tag = "7")]
+ pub baidfpahfgd: i32,
+ #[xor(9092)]
+ #[prost(int32, tag = "6")]
+ pub hdkibenblpe: i32,
+ #[xor(2675)]
+ #[prost(int32, tag = "11")]
+ pub jebmboiocde: i32,
+ #[xor(14112)]
+ #[prost(int32, tag = "14")]
+ pub retcode: i32,
+ #[xor(16379)]
+ #[prost(int32, tag = "3")]
+ pub negmmacmnck: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Bplilleadjc {
+ #[prost(uint32, repeated, tag = "1")]
+ pub diecglcgjod: ::prost::alloc::vec::Vec,
+ #[prost(uint32, repeated, tag = "2")]
+ pub ifhmgfpaacn: ::prost::alloc::vec::Vec,
+ #[prost(uint32, repeated, tag = "3")]
+ pub lokfhlmmobf: ::prost::alloc::vec::Vec,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(753)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Njjppacmoip {
+ #[xor(12249)]
+ #[prost(uint32, tag = "8")]
+ pub goggfbpndmm: u32,
+ #[xor(15134)]
+ #[prost(uint32, tag = "5")]
+ pub item_id: u32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Jjjklojppib {
+ #[prost(float, tag = "6")]
+ pub jolepofhine: f32,
+ #[prost(message, optional, tag = "12")]
+ pub eabhecadfgl: ::core::option::Option,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Lecnflaipon {}
+#[derive(proto_gen::CmdID)]
+#[cmdid(5167)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Fmlkejheddl {
+ #[xor(15220)]
+ #[prost(uint64, tag = "10")]
+ pub jmnpooedngh: u64,
+ #[prost(message, optional, tag = "9")]
+ pub info: ::core::option::Option,
+ #[prost(message, repeated, tag = "8")]
+ pub mafcgflkhic: ::prost::alloc::vec::Vec,
+ #[xor(15011)]
+ #[prost(uint64, tag = "3")]
+ pub dkmbmkcdepe: u64,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Bghgcldpjlp {
+ #[xor(3252)]
+ #[prost(uint32, tag = "15")]
+ pub rank: u32,
+ #[xor(15004)]
+ #[prost(int32, tag = "10")]
+ pub nhekhfpoaaj: i32,
+ #[xor(1430)]
+ #[prost(uint32, tag = "5")]
+ pub level: u32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Lilafdlmjkf {
+ #[prost(message, optional, tag = "11")]
+ pub miodeldcceb: ::core::option::Option,
+ #[xor(1215)]
+ #[prost(uint32, tag = "1")]
+ pub lmiamoihnid: u32,
+ #[xor(15273)]
+ #[prost(uint32, tag = "15")]
+ pub fkjagaehhbf: u32,
+ #[prost(message, optional, tag = "12")]
+ pub hddolcbbile: ::core::option::Option,
+ #[xor(5239)]
+ #[prost(uint32, tag = "14")]
+ pub nmbkbflifhi: u32,
+ #[xor(3820)]
+ #[prost(uint32, tag = "7")]
+ pub ghimebgollb: u32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Hekjjpbclmm {
+ #[prost(int32, tag = "1")]
+ pub gbahkljcigh: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Joonbfjkahp {
+ #[prost(int64, repeated, tag = "1")]
+ pub gccoobifeaf: ::prost::alloc::vec::Vec,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Hpgaamcpfbc {
+ #[prost(uint32, tag = "1")]
+ pub jdofkegmoeb: u32,
+ #[prost(uint32, tag = "2")]
+ pub iakjomgiekd: u32,
+ #[prost(uint32, tag = "3")]
+ pub cgepifmgilf: u32,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(364)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Aglckohdnkf {
+ #[xor(1068)]
+ #[prost(uint32, tag = "3")]
+ pub hlopenbmegp: u32,
+ #[prost(string, tag = "13")]
+ pub mlafgjjebbh: ::prost::alloc::string::String,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Nabgdobbkgh {
+ #[prost(message, repeated, tag = "1")]
+ pub ddpnikdicbk: ::prost::alloc::vec::Vec,
+ #[prost(string, tag = "2")]
+ pub ceehgdlemgn: ::prost::alloc::string::String,
+ #[prost(string, tag = "3")]
+ pub colnhjkmdjp: ::prost::alloc::string::String,
+ #[prost(message, optional, tag = "4")]
+ pub ckcamgdfnfd: ::core::option::Option,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Dpcaompjmkd {
+ #[prost(bool, tag = "3")]
+ pub kboigomlckj: bool,
+ #[prost(string, tag = "7")]
+ pub ljdanhobmko: ::prost::alloc::string::String,
+ #[prost(message, repeated, tag = "15")]
+ pub avatar_list: ::prost::alloc::vec::Vec,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(659)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Leijdkhanbk {
+ #[xor(3946)]
+ #[prost(uint32, tag = "3")]
+ pub bodgohfdpdm: u32,
+ #[prost(uint32, repeated, tag = "11")]
+ pub jbgdcefooig: ::prost::alloc::vec::Vec,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Dgenemmeiil {
+ #[xor(798)]
+ #[prost(uint32, tag = "9")]
+ pub lbmgeignmef: u32,
+ #[prost(message, repeated, tag = "2")]
+ pub jpoafdpjkno: ::prost::alloc::vec::Vec,
+ #[prost(string, tag = "11")]
+ pub bikejihkkad: ::prost::alloc::string::String,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(2111)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Giipifobmej {
+ #[xor(8505)]
+ #[prost(int32, tag = "9")]
+ pub retcode: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Hecpfalakgl {
+ #[prost(uint32, tag = "1")]
+ pub group_id: u32,
+ #[prost(uint32, tag = "2")]
+ pub jhmgppeodmg: u32,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(842)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Faogbahlibj {
+ #[xor(2507)]
+ #[prost(uint32, tag = "3")]
+ pub ihgcjhffkdf: u32,
+ #[prost(map = "uint32, uint32", tag = "8")]
+ pub bikhplpcalp: ::std::collections::HashMap,
+ #[xor(7967)]
+ #[prost(uint32, tag = "10")]
+ pub avatar_id: u32,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(379)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Hmeianihfjl {}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Ahaamgpoikb {
+ #[prost(message, optional, tag = "15")]
+ pub gliihmcajcn: ::core::option::Option,
+ #[prost(message, optional, tag = "5")]
+ pub fcpkblpchml: ::core::option::Option,
+ #[xor(836)]
+ #[prost(uint64, tag = "7")]
+ pub bagbpajonhn: u64,
+ #[prost(message, optional, tag = "12")]
+ pub clnmglnjono: ::core::option::Option,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(2070)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Lekadbbedgd {
+ #[prost(uint32, repeated, tag = "9")]
+ pub jbgdcefooig: ::prost::alloc::vec::Vec,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Ijkfhelddih {
+ #[prost(int32, repeated, tag = "5")]
+ pub unlock_id_list: ::prost::alloc::vec::Vec,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Ihikjcpmnll {
+ #[prost(map = "uint32, uint32", tag = "1")]
+ pub koemgejdgnn: ::std::collections::HashMap,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Dlkgknkenaj {
+ #[prost(bool, tag = "1")]
+ pub pdgbbmbajai: bool,
+ #[prost(bool, tag = "2")]
+ pub kmomiikjnhb: bool,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(2925)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Phhpbchhago {
+ #[xor(15190)]
+ #[prost(int32, tag = "11")]
+ pub retcode: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(377)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Ickpnocnled {
+ #[xor(2992)]
+ #[prost(int32, tag = "7")]
+ pub retcode: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(5114)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Bagjkmfhnko {
+ #[xor(3257)]
+ #[prost(uint64, tag = "15")]
+ pub jmnpooedngh: u64,
+ #[prost(message, optional, tag = "11")]
+ pub info: ::core::option::Option,
+ #[prost(message, repeated, tag = "8")]
+ pub mafcgflkhic: ::prost::alloc::vec::Vec,
+ #[xor(14133)]
+ #[prost(uint64, tag = "1")]
+ pub dkmbmkcdepe: u64,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(2081)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct GetAbyssRewardDataCsReq {}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Hieakkmbifm {
+ #[prost(message, repeated, tag = "3")]
+ pub oldolaoeeia: ::prost::alloc::vec::Vec,
+ #[prost(uint32, repeated, tag = "14")]
+ pub nkppiojcjla: ::prost::alloc::vec::Vec,
+ #[xor(8050)]
+ #[prost(uint32, tag = "10")]
+ pub kjkmchbfeoi: u32,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(3204)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Ddegegiojhk {
+ #[xor(9690)]
+ #[prost(int32, tag = "4")]
+ pub retcode: i32,
+ #[prost(message, optional, tag = "12")]
+ pub fjgommpamai: ::core::option::Option,
+ #[xor(6359)]
+ #[prost(uint32, tag = "15")]
+ pub section_id: u32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Cnfekjdnjoh {
+ #[prost(string, tag = "1")]
+ pub ghobblfkfpm: ::prost::alloc::string::String,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(513)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct BeginnerBattleEndCsReq {
+ #[xor(11367)]
+ #[prost(int64, tag = "7")]
+ pub battle_uid: i64,
+ #[prost(message, optional, tag = "9")]
+ pub battle_statistics: ::core::option::Option,
+ #[xor(8088)]
+ #[prost(int32, tag = "10")]
+ pub battle_id: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Ckbecadmodd {
+ #[xor(4820)]
+ #[prost(uint64, tag = "6")]
+ pub bagbpajonhn: u64,
+ #[xor(13013)]
+ #[prost(uint32, tag = "12")]
+ pub ofolagfmcmo: u32,
+ #[prost(message, optional, tag = "15")]
+ pub haebjdjjang: ::core::option::Option,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(643)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Cgfaciihkhg {
+ #[xor(13313)]
+ #[prost(int32, tag = "5")]
+ pub retcode: i32,
+ #[xor(11896)]
+ #[prost(uint32, tag = "4")]
+ pub bodgohfdpdm: u32,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(506)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct Ghocfocogkb {
+ #[xor(4552)]
+ #[prost(int32, tag = "6")]
+ pub retcode: i32,
+}
+#[derive(proto_gen::CmdID)]
+#[cmdid(2077)]
+#[derive(proto_gen::XorFields)]
+#[allow(clippy::derive_partial_eq_without_eq)]
+#[derive(Clone, PartialEq, ::prost::Message)]
+pub struct GetCollectMapScRsp {
+ #[xor(2089)]
+ #[prost(int32, tag = "15")]
+ pub retcode: i32,
+ #[prost(message, optional, tag = "2")]
+ pub collect_map: ::core::option::Option