2.1.0 functional (#2)

Reviewed-on: WutheringSlaves/wicked-waifus-rs#2
This commit is contained in:
xavo95 2025-01-22 02:12:44 +00:00
parent b316e5f0ac
commit 66231d552f
220 changed files with 3108 additions and 7403874 deletions

3
.gitignore vendored
View file

@ -5,4 +5,5 @@
/loginserver.toml
/gateway.toml
/gameserver.toml
/shorekeeper-protocol/generated
/wicked-waifus-protocol-internal/generated
/wicked-waifus-protocol/generated

6
.gitmodules vendored Normal file
View file

@ -0,0 +1,6 @@
[submodule "data/assets/config-server"]
path = data/assets/config-server
url = https://git.xeondev.com/wickedwaifus/wicked-waifus-config-server-files.git
[submodule "data/assets/game-data"]
path = data/assets/game-data
url = https://git.xeondev.com/wickedwaifus/wicked-waifus-data.git

435
Cargo.lock generated
View file

@ -280,16 +280,6 @@ dependencies = [
"inout",
]
[[package]]
name = "common"
version = "0.1.0"
dependencies = [
"serde",
"toml",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "concurrent-queue"
version = "2.5.0"
@ -299,19 +289,6 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "config-server"
version = "0.1.0"
dependencies = [
"anyhow",
"common",
"serde",
"shorekeeper-http",
"tokio",
"toml",
"tracing",
]
[[package]]
name = "const-oid"
version = "0.9.6"
@ -629,45 +606,6 @@ dependencies = [
"slab",
]
[[package]]
name = "game-server"
version = "0.1.0"
dependencies = [
"anyhow",
"common",
"dashmap 6.1.0",
"hex",
"paste",
"serde",
"shorekeeper-data",
"shorekeeper-database",
"shorekeeper-network",
"shorekeeper-protocol",
"thiserror",
"tokio",
"tracing",
]
[[package]]
name = "gateway-server"
version = "0.1.0"
dependencies = [
"anyhow",
"common",
"dashmap 6.1.0",
"hex",
"kcp",
"paste",
"serde",
"shorekeeper-database",
"shorekeeper-network",
"shorekeeper-protocol",
"shorekeeper-protokey",
"thiserror",
"tokio",
"tracing",
]
[[package]]
name = "generic-array"
version = "0.14.7"
@ -784,19 +722,6 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "hotpatch-server"
version = "0.1.0"
dependencies = [
"anyhow",
"common",
"serde",
"shorekeeper-http",
"tokio",
"toml",
"tracing",
]
[[package]]
name = "http"
version = "1.1.0"
@ -935,7 +860,7 @@ version = "0.1.0"
dependencies = [
"bytes",
"log",
"rand",
"rand 0.8.5",
"thiserror",
"time",
"tokio",
@ -1005,19 +930,6 @@ version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "login-server"
version = "0.1.0"
dependencies = [
"anyhow",
"common",
"serde",
"shorekeeper-database",
"shorekeeper-http",
"tokio",
"tracing",
]
[[package]]
name = "matchers"
version = "0.1.0"
@ -1139,7 +1051,7 @@ dependencies = [
"num-integer",
"num-iter",
"num-traits",
"rand",
"rand 0.8.5",
"smallvec",
"zeroize",
]
@ -1423,8 +1335,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_chacha 0.3.1",
"rand_core 0.6.4",
]
[[package]]
name = "rand"
version = "0.9.0-alpha.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3e256ff62cee3e03def855c4d4260106d2bb1696fdc01af03e9935b993720a5"
dependencies = [
"rand_chacha 0.9.0-alpha.2",
"rand_core 0.9.0-alpha.2",
"zerocopy",
]
[[package]]
@ -1434,7 +1357,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
"rand_core 0.6.4",
]
[[package]]
name = "rand_chacha"
version = "0.9.0-alpha.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d299e9db34f6623b2a9e86c015d6e173d5f46d64d4b9b8cc46ae8a982a50b04c"
dependencies = [
"ppv-lite86",
"rand_core 0.9.0-alpha.2",
]
[[package]]
@ -1446,6 +1379,16 @@ dependencies = [
"getrandom",
]
[[package]]
name = "rand_core"
version = "0.9.0-alpha.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4e93f5a5e3c528cda9acb0928c31b2ba868c551cc46e67b778075e34aab9906"
dependencies = [
"getrandom",
"zerocopy",
]
[[package]]
name = "rayon"
version = "1.10.0"
@ -1557,7 +1500,7 @@ dependencies = [
"num-traits",
"pkcs1",
"pkcs8",
"rand_core",
"rand_core 0.6.4",
"signature",
"spki",
"subtle",
@ -1664,9 +1607,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.128"
version = "1.0.135"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8"
checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9"
dependencies = [
"itoa",
"memchr",
@ -1684,6 +1627,17 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_repr"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_spanned"
version = "0.6.7"
@ -1742,90 +1696,6 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "shorekeeper-data"
version = "0.1.0"
dependencies = [
"paste",
"serde",
"serde_json",
"thiserror",
]
[[package]]
name = "shorekeeper-database"
version = "0.1.0"
dependencies = [
"serde",
"sqlx",
]
[[package]]
name = "shorekeeper-http"
version = "0.1.0"
dependencies = [
"aes",
"axum",
"axum-server",
"cbc",
"rbase64",
"serde",
"thiserror",
"tower-http",
"tracing",
]
[[package]]
name = "shorekeeper-network"
version = "0.1.0"
dependencies = [
"byteorder",
"serde",
"shorekeeper-protocol",
"tokio",
"zeromq",
]
[[package]]
name = "shorekeeper-protocol"
version = "0.1.0"
dependencies = [
"byteorder",
"crc32fast",
"prettyplease",
"prost",
"prost-build",
"quote",
"serde",
"serde_json",
"shorekeeper-protocol-derive",
"syn",
"thiserror",
]
[[package]]
name = "shorekeeper-protocol-derive"
version = "0.1.0"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "shorekeeper-protokey"
version = "0.1.0"
dependencies = [
"aes",
"cipher",
"rand",
"rbase64",
"rsa",
"serde",
"thiserror",
"tracing",
]
[[package]]
name = "signal-hook-registry"
version = "1.4.2"
@ -1842,7 +1712,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
dependencies = [
"digest",
"rand_core",
"rand_core 0.6.4",
]
[[package]]
@ -2025,7 +1895,7 @@ dependencies = [
"memchr",
"once_cell",
"percent-encoding",
"rand",
"rand 0.8.5",
"rsa",
"serde",
"sha1",
@ -2064,7 +1934,7 @@ dependencies = [
"md-5",
"memchr",
"once_cell",
"rand",
"rand 0.8.5",
"serde",
"serde_json",
"sha2",
@ -2483,9 +2353,9 @@ dependencies = [
[[package]]
name = "uuid"
version = "1.10.0"
version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314"
checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a"
dependencies = [
"getrandom",
]
@ -2539,6 +2409,199 @@ dependencies = [
"wasite",
]
[[package]]
name = "wicked-waifus-commons"
version = "0.1.0"
dependencies = [
"serde",
"toml",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "wicked-waifus-config-server"
version = "0.1.0"
dependencies = [
"anyhow",
"serde",
"tokio",
"toml",
"tracing",
"wicked-waifus-commons",
"wicked-waifus-http",
]
[[package]]
name = "wicked-waifus-data"
version = "0.1.0"
dependencies = [
"paste",
"serde",
"serde_json",
"serde_repr",
"thiserror",
]
[[package]]
name = "wicked-waifus-database"
version = "0.1.0"
dependencies = [
"serde",
"sqlx",
]
[[package]]
name = "wicked-waifus-game-server"
version = "0.1.0"
dependencies = [
"anyhow",
"dashmap 6.1.0",
"hex",
"paste",
"rand 0.9.0-alpha.2",
"serde",
"thiserror",
"tokio",
"tracing",
"uuid",
"wicked-waifus-commons",
"wicked-waifus-data",
"wicked-waifus-database",
"wicked-waifus-network",
"wicked-waifus-protocol",
"wicked-waifus-protocol-internal",
]
[[package]]
name = "wicked-waifus-gateway-server"
version = "0.1.0"
dependencies = [
"anyhow",
"dashmap 6.1.0",
"hex",
"kcp",
"paste",
"serde",
"thiserror",
"tokio",
"tracing",
"wicked-waifus-commons",
"wicked-waifus-database",
"wicked-waifus-network",
"wicked-waifus-protocol",
"wicked-waifus-protocol-internal",
"wicked-waifus-protokey",
]
[[package]]
name = "wicked-waifus-hotpatch-server"
version = "0.1.0"
dependencies = [
"anyhow",
"serde",
"tokio",
"toml",
"tracing",
"wicked-waifus-commons",
"wicked-waifus-http",
]
[[package]]
name = "wicked-waifus-http"
version = "0.1.0"
dependencies = [
"aes",
"axum",
"axum-server",
"cbc",
"rbase64",
"serde",
"thiserror",
"tower-http",
"tracing",
]
[[package]]
name = "wicked-waifus-login-server"
version = "0.1.0"
dependencies = [
"anyhow",
"serde",
"tokio",
"tracing",
"wicked-waifus-commons",
"wicked-waifus-database",
"wicked-waifus-http",
]
[[package]]
name = "wicked-waifus-network"
version = "0.1.0"
dependencies = [
"byteorder",
"serde",
"tokio",
"zeromq",
]
[[package]]
name = "wicked-waifus-protocol"
version = "0.1.0"
source = "git+https://git.xeondev.com/wickedwaifus/wicked-waifus-proto#c0d23e19e2b5fd32bf814b3bf379b39ea6d5bc76"
dependencies = [
"byteorder",
"crc32fast",
"prettyplease",
"prost",
"prost-build",
"quote",
"serde",
"serde_json",
"syn",
"thiserror",
"wicked-waifus-protocol-derive",
]
[[package]]
name = "wicked-waifus-protocol-derive"
version = "0.1.0"
source = "git+https://git.xeondev.com/wickedwaifus/wicked-waifus-proto#c0d23e19e2b5fd32bf814b3bf379b39ea6d5bc76"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "wicked-waifus-protocol-internal"
version = "0.1.0"
dependencies = [
"byteorder",
"crc32fast",
"prost",
"prost-build",
"serde",
"serde_json",
"thiserror",
"wicked-waifus-protocol",
"wicked-waifus-protocol-derive",
]
[[package]]
name = "wicked-waifus-protokey"
version = "0.1.0"
dependencies = [
"aes",
"cipher",
"rand 0.8.5",
"rbase64",
"rsa",
"serde",
"thiserror",
"tracing",
]
[[package]]
name = "winapi"
version = "0.3.9"
@ -2764,7 +2827,7 @@ dependencies = [
"num-traits",
"once_cell",
"parking_lot",
"rand",
"rand 0.8.5",
"regex",
"thiserror",
"tokio",

View file

@ -1,5 +1,5 @@
[workspace]
members = ["common", "config-server", "hotpatch-server", "login-server", "gateway-server", "gateway-server/kcp", "shorekeeper-database", "shorekeeper-http", "shorekeeper-protokey", "shorekeeper-protocol", "shorekeeper-protocol/shorekeeper-protocol-derive", "game-server", "shorekeeper-network", "shorekeeper-data"]
members = ["wicked-waifus-commons", "wicked-waifus-config-server", "wicked-waifus-hotpatch-server", "wicked-waifus-login-server", "wicked-waifus-gateway-server", "wicked-waifus-gateway-server/kcp", "wicked-waifus-database", "wicked-waifus-http", "wicked-waifus-protokey", "wicked-waifus-protocol-internal", "wicked-waifus-game-server", "wicked-waifus-network", "wicked-waifus-data"]
resolver = "2"
[workspace.package]
@ -20,12 +20,14 @@ sqlx = { version = "0.8.2", features = ["postgres", "runtime-tokio-rustls"] }
aes = "0.8.4"
cbc = { version = "0.1.2", features = ["alloc"] }
cipher = "0.4.4"
crc32fast = "1.4.2"
rand = "0.8.5"
rsa = { version = "0.9.6", features = ["pem"] }
# Serialization
serde = { version = "1.0.209", features = ["derive"] }
serde_json = "1.0.128"
serde_repr = "0.1.19"
toml = "0.8.19"
prost = "0.13.2"
prost-build = "0.13.2"
@ -38,22 +40,23 @@ rbase64 = "2.0.3"
dashmap = "6.1.0"
hex = "0.4.3"
byteorder = "1.5.0"
crc32fast = "1.4.2"
# Tracing
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
# Internal
kcp = { path = "gateway-server/kcp" }
common = { path = "common" }
shorekeeper-http = { path = "shorekeeper-http" }
shorekeeper-data = { path = "shorekeeper-data" }
shorekeeper-database = { path = "shorekeeper-database" }
shorekeeper-network = { path = "shorekeeper-network" }
shorekeeper-protocol = { path = "shorekeeper-protocol" }
shorekeeper-protocol-derive = { path = "shorekeeper-protocol/shorekeeper-protocol-derive" }
shorekeeper-protokey = { path = "shorekeeper-protokey" }
kcp = { path = "wicked-waifus-gateway-server/kcp" }
wicked-waifus-commons = { path = "wicked-waifus-commons" }
wicked-waifus-http = { path = "wicked-waifus-http" }
wicked-waifus-data = { path = "wicked-waifus-data" }
wicked-waifus-database = { path = "wicked-waifus-database" }
wicked-waifus-network = { path = "wicked-waifus-network" }
wicked-waifus-protocol-internal = { path = "wicked-waifus-protocol-internal" }
wicked-waifus-protokey = { path = "wicked-waifus-protokey" }
wicked-waifus-protocol = { git = "https://git.xeondev.com/wickedwaifus/wicked-waifus-proto" }
wicked-waifus-protocol-derive = { git = "https://git.xeondev.com/wickedwaifus/wicked-waifus-proto" }
[profile.release]
strip = true # Automatically strip symbols from the binary.

View file

@ -2,5 +2,5 @@ FROM alpine:3.20
ARG MICROSERVICE
WORKDIR /app
COPY --from=wicked-waifus-builder:1.4.0-SNAPSHOT /app/target/release/$MICROSERVICE ./service
COPY --from=wicked-waifus-builder:2.1.0-SNAPSHOT /app/target/release/$MICROSERVICE ./service
CMD ["./service"]

View file

@ -1,9 +1,12 @@
# Shorekeeper
# Camellya
![Screenshot](https://git.xeondev.com/Shorekeeper/Shorekeeper/raw/branch/master/screenshot.png)
![Screenshot](screenshot.png)
## About
**Shorekeeper is an open-source Wuthering Waves server emulator written in Rust**. The goal of this project is to ensure a clean, easy-to-understand code environment. Shorekeeper uses **tokio** for asynchronous networking operations, **axum** as http framework and **ZeroMQ** for communication between servers. It also implements **performant and extensible ECS** for emulation of the game world.
**Wicked Waifus is an open-source Wuthering Waves server emulator written in Rust**.
The goal of this project is to ensure a clean, easy-to-understand code environment.
Wicked Waifus uses **tokio** for asynchronous networking operations, **axum** as http framework and **ZeroMQ** for communication between servers.
It also implements **performant and extensible ECS** for emulation of the game world.
## Getting started
#### Requirements
@ -15,13 +18,13 @@
##### a) building from sources
```sh
git clone https://git.xeondev.com/Shorekeeper/Shorekeeper.git
cd Shorekeeper
cargo run --bin config-server
cargo run --bin hotpatch-server
cargo run --bin login-server
cargo run --bin gateway-server
cargo run --bin game-server
git clone --recursive https://git.xeondev.com/wickedwaifus/wicked-waifus-rs.git
cd wicked-waifus-rs
cargo run --bin wicked-waifus-config-server
cargo run --bin wicked-waifus-hotpatch-server
cargo run --bin wicked-waifus-login-server
cargo run --bin wicked-waifus-gateway-server
cargo run --bin wicked-waifus-game-server
```
##### b) building from sources(docker edition)
@ -40,9 +43,9 @@ docker compose up -d
```
##### c) using pre-built binaries
Navigate to the [Releases](https://git.xeondev.com/Shorekeeper/Shorekeeper/releases)
Navigate to the [Releases](https://git.xeondev.com/wickedwaifus/wicked-waifus-rs/releases)
page and download the latest release for your platform.<br>
Launch all servers: `config-server`, `hotpatch-server`, `login-server`, `gateway-server`, `game-server`
Launch all servers: `wicked-waifus-config-server`, `wicked-waifus-hotpatch-server`, `wicked-waifus-login-server`, `wicked-waifus-gateway-server`, `wicked-waifus-game-server`
##### NOTE: you don't have to install Rust and Protoc if you're going to use pre-built binaries, although the preferred way is building from sources.<br>We don't provide any support for pre-built binaries.
@ -57,15 +60,15 @@ You have to specify credentials for **PostgreSQL**<br>
host = "localhost:5432"
user_name = "postgres"
password = ""
db_name = "shorekeeper"
db_name = "wicked_waifus_db"
```
##### NOTE: don't forget to create database with specified `db_name` (default: `shorekeeper`). For example, you can do so with PgAdmin.
##### NOTE: don't forget to create database with specified `db_name` (default: `wicked_waifus_db`). For example, you can do so with PgAdmin.
#### Data
The data files: Logic JSON collections (`assets/logic/json`) and config/hotpatch indexes (`assets/config`, `assets/hotpatch`) are included in this repository. Keep in mind that you need to have the `assets` subdirectory in current working directory.
The data files: Logic JSON collections (`data/assets/game-data/BinData`) and config/hotpatch indexes (`data/assets/config-server`, `data/assets/hotpatch-server`) are included in this repository. Keep in mind that you need to have the `data` subdirectory in current working directory.
#### Connecting
You have to download client of Wuthering Waves Beta 1.3, apply the [shorekeeper-patch](https://git.xeondev.com/xeon/shorekeeper-patch/releases) and add necessary `.pak` files, which you can get here: [shorekeeper-pak](https://git.xeondev.com/Shorekeeper/shorekeeper-pak)
You have to download client of Wuthering Waves Beta 1.3, apply the [wicked-waifus-win-patch](https://git.xeondev.com/wickedwaifus/wicked-waifus-win-patch/releases) and add necessary `.pak` files, which you can get here: [wicked-waifus-pak](https://git.xeondev.com/wickedwaifus/wicked-waifus-pak)
### Troubleshooting
[Visit our discord](https://discord.gg/reversedrooms) if you have any questions/issues

View file

@ -1,64 +0,0 @@
{
"default": {
"CdnUrl": [
{
"url": "https://cdn-huoshan-cn-mc.aki-game.com/prod/client/",
"weight": "0"
},
{
"url": "https://cdn-qiniu-cn-mc.aki-game.com/prod/client/",
"weight": "4181"
},
{
"url": "https://cdn-qcloud-cn-mc.aki-game.com/prod/client/",
"weight": "2937"
},
{
"url": "https://cdn-aliyun-cn-mc.aki-game.com/prod/client/",
"weight": "0"
}
],
"SecondaryUrl": [],
"PriceRatio": 1,
"SpeedRatio": 1,
"GachaUrl": {
"GachaRecord": "https://aki-gm-resources.aki-game.com",
"GachaPoolDetail": "https://aki-gm-resources.aki-game.com"
},
"LogReport": {
"name": "aki-upload-log-1319073642",
"region": "ap-shanghai"
},
"PackageUpdateDescUrl": {
"MainUrl": "https://aki-gm-resources-back.aki-game.com/force_update/UpdateDesc.html",
"SubUrl": "https://aki-gm-resources-back-qiniu.aki-game.com/force_update/UpdateDesc.html"
},
"PackageUpdateUrl": {
"MainUrl": "https://aki-gm-resources-back.aki-game.com/force_update/UpdateJs.html",
"SubUrl": "https://aki-gm-resources-back-qiniu.aki-game.com/force_update/UpdateJs.html"
},
"TDCfg": {
"AppID": "7be70c9c181f4fa8bc013e9b89d2b63b",
"URL": "http://cn-datareceiver.aki-game.com"
},
"GmOpen": false,
"IosAuditFirstDownloadTip": false,
"NoticeUrl": "https://aki-gm-resources-back.aki-game.com",
"MixUri": "e66lKLx7RnUf9QlkMCGaW0jdyjRV1weo",
"ResUri": "e66lKLx7RnUf9QlkMCGaW0jdyjRV1weo",
"LoginServers": [
{
"id": "76402e5b20be2c39f095a152090afddc",
"ip": "https://login-sh.aki-game.com",
"name": "鸣潮"
}
],
"PrivateServers": {
"enable": false,
"serverUrl": ""
}
},
"p1": {
"IosAuditFirstDownloadTip": false
}
}

View file

@ -1,60 +0,0 @@
{
"default": {
"CdnUrl": [
{
"url": "https://cdn-huoshan-cn-mc.aki-game.com/prod/client/",
"weight": "2323"
},
{
"url": "https://cdn-qiniu-cn-mc.aki-game.com/prod/client/",
"weight": "1"
},
{
"url": "https://cdn-qcloud-cn-mc.aki-game.com/prod/client/",
"weight": "5443"
}
],
"SecondaryUrl": [],
"PriceRatio": 1,
"SpeedRatio": 1,
"GachaUrl": {
"GachaRecord": "http://127.0.0.1:10001/gacha/record",
"GachaPoolDetail": "http://127.0.0.1:10001/gacha/detail"
},
"LogReport": {
"name": "pioneer-upload-log-1319073642",
"region": "dev-reversedrooms"
},
"PackageUpdateDescUrl": {
"MainUrl": "http://127.0.0.1:10001/force_update/UpdateDesc.html",
"SubUrl": "http://127.0.0.1:10001/force_update/UpdateDesc.html"
},
"PackageUpdateUrl": {
"MainUrl": "http://127.0.0.1:10001/force_update/UpdateJs.html",
"SubUrl": "http://127.0.0.1:10001/force_update/UpdateJs.html"
},
"TDCfg": {
"AppID": "3e2e647670b7498fa645eb9574f78c2c",
"URL": "http://127.0.0.1:10001/TDCfg"
},
"GmOpen": false,
"IosAuditFirstDownloadTip": false,
"NoticeUrl": "http://127.0.0.1:10001/notice",
"MixUri": "fcQrWOPC2RkghpzsAE2kyGWD37QTm2mR",
"ResUri": "fcQrWOPC2RkghpzsAE2kyGWD37QTm2mR",
"LoginServers": [
{
"id": "f9e0fc655c1931bc03ad976e9fc14473",
"ip": "http://127.0.0.1:5500",
"name": "Camellya"
}
],
"PrivateServers": {
"enable": false,
"serverUrl": ""
}
},
"p1": {
"IosAuditFirstDownloadTip": false
}
}

View file

@ -1,64 +0,0 @@
{
"default": {
"CdnUrl": [
{
"url": "https://cdn-huoshan-cn-mc.aki-game.com/prod/client/",
"weight": "2323"
},
{
"url": "https://cdn-qiniu-cn-mc.aki-game.com/prod/client/",
"weight": "0"
},
{
"url": "https://cdn-qcloud-cn-mc.aki-game.com/prod/client/",
"weight": "5443"
},
{
"url": "https://cdn-aliyun-cn-mc.aki-game.com/prod/client/",
"weight": "0"
}
],
"SecondaryUrl": [],
"PriceRatio": 1,
"SpeedRatio": 1,
"GachaUrl": {
"GachaRecord": "http://127.0.0.1:10001/gacha/record",
"GachaPoolDetail": "http://127.0.0.1:10001/gacha/detail"
},
"LogReport": {
"name": "pioneer-upload-log-1319073642",
"region": "dev-reversedrooms"
},
"PackageUpdateDescUrl": {
"MainUrl": "http://127.0.0.1:10001/force_update/UpdateDesc.html",
"SubUrl": "http://127.0.0.1:10001/force_update/UpdateDesc.html"
},
"PackageUpdateUrl": {
"MainUrl": "http://127.0.0.1:10001/force_update/UpdateJs.html",
"SubUrl": "http://127.0.0.1:10001/force_update/UpdateJs.html"
},
"TDCfg": {
"AppID": "3e2e647670b7498fa645eb9574f78c2c",
"URL": "http://127.0.0.1:10001/TDCfg"
},
"GmOpen": false,
"IosAuditFirstDownloadTip": false,
"NoticeUrl": "http://127.0.0.1:10001/notice",
"MixUri": "rODM5DcqOhYsIOtsEuZWNGFa2guZgl57",
"ResUri": "rODM5DcqOhYsIOtsEuZWNGFa2guZgl57",
"LoginServers": [
{
"id": "f9e0fc655c1931bc03ad976e9fc14473",
"ip": "http://127.0.0.1:5500",
"name": "Shorekeeper"
}
],
"PrivateServers": {
"enable": false,
"serverUrl": ""
}
},
"p1": {
"IosAuditFirstDownloadTip": false
}
}

View file

@ -1,115 +0,0 @@
{
"default": {
"CdnUrl": [
{
"url": "https://cdn-aws-hw-mc.aki-game.net/prod/client/",
"weight": "829"
},
{
"url": "https://cdn-qcloud-hw-mc.aki-game.net/prod/client/",
"weight": "0"
},
{
"url": "https://cdn-akamai-hw-mc.aki-game.net/prod/client/",
"weight": "262"
},
{
"url": "https://cdn-huoshan-hw-mc.aki-game.net/prod/client/",
"weight": "829"
}
],
"SecondaryUrl": [],
"PriceRatio": 1,
"SpeedRatio": 1,
"GachaUrl": {
"GachaRecord": "https://aki-gm-resources-oversea.aki-game.net",
"GachaPoolDetail": "https://aki-gm-resources-oversea.aki-game.net"
},
"LogReport": {
"name": "hw-aki-upload-log-1319073642",
"region": "ap-singapore"
},
"PackageUpdateDescUrl": {
"MainUrl": "https://aki-gm-resources-back.aki-game.net/force_update/UpdateDesc.html",
"SubUrl": "https://aki-gm-resources-back-aws.aki-game.net/force_update/UpdateDesc.html"
},
"PackageUpdateUrl": {
"MainUrl": "https://aki-gm-resources-back.aki-game.net/force_update/UpdateJs.html",
"SubUrl": "https://aki-gm-resources-back-aws.aki-game.net/force_update/UpdateJs.html"
},
"GARUrl": "https://gar-service.aki-game.net",
"TDCfg": {
"URL": "http://us-datareceiver.aki-game.net",
"AppID": "bf3f44edc6cf43c582e347ba660876c0"
},
"GmOpen": false,
"IosAuditFirstDownloadTip": false,
"NoticeUrl": "https://aki-gm-resources-back.aki-game.net",
"MixUri": "u4S3uXaif7gNKnNGnbZ6WnW67vWFmQgd",
"ResUri": "u4S3uXaif7gNKnNGnbZ6WnW67vWFmQgd",
"LoginServers": [
{
"PingUrl": "49.51.79.239",
"Region": "America",
"TDCfg": {
"AppID": "12c7c870b57541caa2093e275212f083",
"URL": "http://us-datareceiver.aki-game.net"
},
"id": "591d6af3a3090d8ea00d8f86cf6d7501",
"ip": "https://login-us.aki-game.net",
"name": "America"
},
{
"PingUrl": "124.156.236.245",
"Region": "Asia",
"TDCfg": {
"AppID": "dc2e8c02609546e89d78c2eb2974becb",
"URL": "http://jp-datareceiver.aki-game.net"
},
"id": "86d52186155b148b5c138ceb41be9650",
"ip": "https://login-jp.aki-game.net",
"name": "Asia"
},
{
"PingUrl": "49.51.129.88",
"Region": "Europe",
"TDCfg": {
"AppID": "0fb77e4801db41a7a1fb1a3431625fbd",
"URL": "http://eu-datareceiver.aki-game.net"
},
"id": "6eb2a235b30d05efd77bedb5cf60999e",
"ip": "https://login-eu.aki-game.net",
"name": "Europe"
},
{
"PingUrl": "43.129.150.38",
"Region": "HMT",
"TDCfg": {
"AppID": "5ccd297c928d405a9e6b18a122f4d48d",
"URL": "http://hk-datareceiver.aki-game.net"
},
"id": "919752ae5ea09c1ced910dd668a63ffb",
"ip": "https://login-hk.aki-game.net",
"name": "HMT(HK, MO, TW)"
},
{
"PingUrl": "101.33.100.22",
"Region": "SEA",
"TDCfg": {
"AppID": "dffd1143291b4877a8866fb24c623038",
"URL": "http://as-datareceiver.aki-game.net"
},
"id": "10cd7254d57e58ae560b15d51e34b4c8",
"ip": "https://login-sg.aki-game.net",
"name": "SEA"
}
],
"PrivateServers": {
"enable": false,
"serverUrl": ""
}
},
"p1": {
"IosAuditFirstDownloadTip": false
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,246 +0,0 @@
[
{
"PhantomSkillId": 1004,
"Name": "ExploreTools_1004_Name",
"SkillType": 1,
"CurrentSkillInfo": "ExploreTools_1004_CurrentSkillInfo",
"HelpId": 0,
"Icon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT3.SP_IconT3",
"BackGround": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT3.SP_IconT3",
"BattleViewIcon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT3.SP_IconT3",
"SortId": 3,
"AutoFill": true,
"ShowUnlock": false,
"SkillGroupId": 1,
"IsUseInPhantomTeam": false,
"Cost": {},
"Authorization": {},
"SummonConfigId": 0
},
{
"PhantomSkillId": 1001,
"Name": "ExploreTools_1001_Name",
"SkillType": 1,
"CurrentSkillInfo": "ExploreTools_1001_CurrentSkillInfo",
"HelpId": 0,
"Icon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT6.SP_IconT6",
"BackGround": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT6.SP_IconT6",
"BattleViewIcon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT6.SP_IconT6",
"SortId": 1,
"AutoFill": true,
"ShowUnlock": false,
"SkillGroupId": 1,
"IsUseInPhantomTeam": false,
"Cost": {},
"Authorization": {},
"SummonConfigId": 0
},
{
"PhantomSkillId": 1003,
"Name": "ExploreTools_1003_Name",
"SkillType": 1,
"CurrentSkillInfo": "ExploreTools_1003_CurrentSkillInfo",
"HelpId": 0,
"Icon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT1.SP_IconT1",
"BackGround": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT1.SP_IconT1",
"BattleViewIcon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT1.SP_IconT1",
"SortId": 4,
"AutoFill": true,
"ShowUnlock": false,
"SkillGroupId": 1,
"IsUseInPhantomTeam": false,
"Cost": {},
"Authorization": {},
"SummonConfigId": 0
},
{
"PhantomSkillId": 1005,
"Name": "ExploreTools_1005_Name",
"SkillType": 2,
"CurrentSkillInfo": "ExploreTools_1005_CurrentSkillInfo",
"HelpId": 0,
"Icon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT2.SP_IconT2",
"BackGround": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT2.SP_IconT2",
"BattleViewIcon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT2.SP_IconT2",
"SortId": 5,
"AutoFill": false,
"ShowUnlock": false,
"SkillGroupId": 1,
"IsUseInPhantomTeam": false,
"Cost": {},
"Authorization": {},
"SummonConfigId": 0
},
{
"PhantomSkillId": 1006,
"Name": "ExploreTools_1006_Name",
"SkillType": 2,
"CurrentSkillInfo": "ExploreTools_1006_CurrentSkillInfo",
"HelpId": 0,
"Icon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT5.SP_IconT5",
"BackGround": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT5.SP_IconT5",
"BattleViewIcon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT5.SP_IconT5",
"SortId": 6,
"AutoFill": false,
"ShowUnlock": false,
"SkillGroupId": 1,
"IsUseInPhantomTeam": false,
"Cost": {},
"Authorization": {},
"SummonConfigId": 0
},
{
"PhantomSkillId": 1007,
"Name": "ExploreTools_1007_Name",
"SkillType": 1,
"CurrentSkillInfo": "ExploreTools_1007_CurrentSkillInfo",
"HelpId": 0,
"Icon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT29.SP_IconT29",
"BackGround": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT29.SP_IconT29",
"BattleViewIcon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT29.SP_IconT29",
"SortId": 7,
"AutoFill": false,
"ShowUnlock": false,
"SkillGroupId": 1,
"IsUseInPhantomTeam": false,
"Cost": {},
"Authorization": {},
"SummonConfigId": 0
},
{
"PhantomSkillId": 1009,
"Name": "ExploreTools_1009_Name",
"SkillType": 1,
"CurrentSkillInfo": "ExploreTools_1009_CurrentSkillInfo",
"HelpId": 0,
"Icon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT9.SP_IconT9",
"BackGround": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT9.SP_IconT9",
"BattleViewIcon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT9.SP_IconT9",
"SortId": 9,
"AutoFill": false,
"ShowUnlock": false,
"SkillGroupId": 1,
"IsUseInPhantomTeam": true,
"Cost": {},
"Authorization": {},
"SummonConfigId": 0
},
{
"PhantomSkillId": 3001,
"Name": "ExploreTools_1009_Name",
"SkillType": 3,
"CurrentSkillInfo": "ExploreTools_1009_CurrentSkillInfo",
"HelpId": 0,
"Icon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT9.SP_IconT9",
"BackGround": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT9.SP_IconT9",
"BattleViewIcon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT9.SP_IconT9",
"SortId": 10,
"AutoFill": false,
"ShowUnlock": false,
"SkillGroupId": 1,
"IsUseInPhantomTeam": false,
"Cost": {},
"Authorization": {},
"SummonConfigId": 0
},
{
"PhantomSkillId": 3002,
"Name": "ExploreTools_1009_Name",
"SkillType": 3,
"CurrentSkillInfo": "ExploreTools_1009_CurrentSkillInfo",
"HelpId": 0,
"Icon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT9.SP_IconT9",
"BackGround": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT9.SP_IconT9",
"BattleViewIcon": "/Game/Aki/UI/UIResources/UiSkillswitching/Atlas/SP_SkillswitchingItemNone.SP_SkillswitchingItemNone",
"SortId": 10,
"AutoFill": false,
"ShowUnlock": false,
"SkillGroupId": 1,
"IsUseInPhantomTeam": false,
"Cost": {},
"Authorization": {},
"SummonConfigId": 0
},
{
"PhantomSkillId": 1010,
"Name": "ExploreTools_1010_Name",
"SkillType": 1,
"CurrentSkillInfo": "ExploreTools_1010_CurrentSkillInfo",
"HelpId": 30,
"Icon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT30.SP_IconT30",
"BackGround": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT30.SP_IconT30",
"BattleViewIcon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT30.SP_IconT30",
"SortId": 11,
"AutoFill": true,
"ShowUnlock": false,
"SkillGroupId": 1,
"IsUseInPhantomTeam": false,
"Cost": {
"10808": 1
},
"Authorization": {},
"SummonConfigId": 0
},
{
"PhantomSkillId": 1011,
"Name": "ExploreTools_1011_Name",
"SkillType": 1,
"CurrentSkillInfo": "ExploreTools_1011_CurrentSkillInfo",
"HelpId": 28,
"Icon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT32.SP_IconT32",
"BackGround": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT32.SP_IconT32",
"BattleViewIcon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT32.SP_IconT32",
"SortId": 12,
"AutoFill": true,
"ShowUnlock": false,
"SkillGroupId": 1,
"IsUseInPhantomTeam": false,
"Cost": {
"10807": 1
},
"Authorization": {
"1": 10805,
"900": 10805
},
"SummonConfigId": 0
},
{
"PhantomSkillId": 1012,
"Name": "ExploreTools_1012_Name",
"SkillType": 1,
"CurrentSkillInfo": "ExploreTools_1012_CurrentSkillInfo",
"HelpId": 29,
"Icon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT31.SP_IconT31",
"BackGround": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT31.SP_IconT31",
"BattleViewIcon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT31.SP_IconT31",
"SortId": 13,
"AutoFill": true,
"ShowUnlock": false,
"SkillGroupId": 1,
"IsUseInPhantomTeam": false,
"Cost": {},
"Authorization": {
"1": 10806,
"900": 10806
},
"SummonConfigId": 0
},
{
"PhantomSkillId": 1013,
"Name": "ExploreTools_1013_Name",
"SkillType": 1,
"CurrentSkillInfo": "ExploreTools_1013_CurrentSkillInfo",
"HelpId": 0,
"Icon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT34.SP_IconT34",
"BackGround": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT34.SP_IconT34",
"BattleViewIcon": "/Game/Aki/UI/UIResources/Common/Atlas/SkillIcon/SkillIconNor/SP_IconT34.SP_IconT34",
"SortId": 14,
"AutoFill": true,
"ShowUnlock": false,
"SkillGroupId": 1,
"IsUseInPhantomTeam": false,
"Cost": {},
"Authorization": {},
"SummonConfigId": 24000022
}
]

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,12 +1,12 @@
docker build -t wicked-waifus-builder:1.4.0-SNAPSHOT -f Dockerfile-builder .
docker build -t wicked-waifus-builder:2.1.0-SNAPSHOT -f Dockerfile-builder .
docker build -t wicked-waifus-config-server:1.4.0-SNAPSHOT --build-arg MICROSERVICE=config-server -f Dockerfile-service .
docker build -t wicked-waifus-hotpatch-server:1.4.0-SNAPSHOT --build-arg MICROSERVICE=hotpatch-server -f Dockerfile-service .
docker build -t wicked-waifus-login-server:1.4.0-SNAPSHOT --build-arg MICROSERVICE=login-server -f Dockerfile-service .
docker build -t wicked-waifus-gateway-server:1.4.0-SNAPSHOT --build-arg MICROSERVICE=gateway-server -f Dockerfile-service .
docker build -t wicked-waifus-game-server:1.4.0-SNAPSHOT --build-arg MICROSERVICE=game-server -f Dockerfile-service .
docker build -t wicked-waifus-config-server:2.1.0-SNAPSHOT --build-arg MICROSERVICE=wicked-waifus-config-server -f Dockerfile-service .
docker build -t wicked-waifus-hotpatch-server:2.1.0-SNAPSHOT --build-arg MICROSERVICE=wicked-waifus-server -f Dockerfile-service .
docker build -t wicked-waifus-login-server:2.1.0-SNAPSHOT --build-arg MICROSERVICE=wicked-waifus-login-server -f Dockerfile-service .
docker build -t wicked-waifus-gateway-server:2.1.0-SNAPSHOT --build-arg MICROSERVICE=wicked-waifus-gateway-server -f Dockerfile-service .
docker build -t wicked-waifus-game-server:2.1.0-SNAPSHOT --build-arg MICROSERVICE=wicked-waifus-game-server -f Dockerfile-service .
docker rmi wicked-waifus-builder:1.4.0-SNAPSHOT
docker rmi wicked-waifus-builder:2.1.0-SNAPSHOT
: Persistence for the application
: docker volume create wicked-waifus-postgres-vol

View file

@ -1,12 +1,12 @@
docker build -t wicked-waifus-builder:1.4.0-SNAPSHOT -f Dockerfile-builder .
docker build -t wicked-waifus-builder:2.1.0-SNAPSHOT -f Dockerfile-builder .
docker build -t wicked-waifus-config-server:1.4.0-SNAPSHOT --build-arg MICROSERVICE=config-server -f Dockerfile-service .
docker build -t wicked-waifus-hotpatch-server:1.4.0-SNAPSHOT --build-arg MICROSERVICE=hotpatch-server -f Dockerfile-service .
docker build -t wicked-waifus-login-server:1.4.0-SNAPSHOT --build-arg MICROSERVICE=login-server -f Dockerfile-service .
docker build -t wicked-waifus-gateway-server:1.4.0-SNAPSHOT --build-arg MICROSERVICE=gateway-server -f Dockerfile-service .
docker build -t wicked-waifus-game-server:1.4.0-SNAPSHOT --build-arg MICROSERVICE=game-server -f Dockerfile-service .
docker build -t wicked-waifus-config-server:2.1.0-SNAPSHOT --build-arg MICROSERVICE=wicked-waifus-config-server -f Dockerfile-service .
docker build -t wicked-waifus-hotpatch-server:2.1.0-SNAPSHOT --build-arg MICROSERVICE=wicked-waifus-hotpatch-server -f Dockerfile-service .
docker build -t wicked-waifus-login-server:2.1.0-SNAPSHOT --build-arg MICROSERVICE=wicked-waifus-login-server -f Dockerfile-service .
docker build -t wicked-waifus-gateway-server:2.1.0-SNAPSHOT --build-arg MICROSERVICE=wicked-waifus-gateway-server -f Dockerfile-service .
docker build -t wicked-waifus-game-server:2.1.0-SNAPSHOT --build-arg MICROSERVICE=wicked-waifus-game-server -f Dockerfile-service .
docker rmi wicked-waifus-builder:1.4.0-SNAPSHOT
docker rmi wicked-waifus-builder:2.1.0-SNAPSHOT
# Persistence for the application
# docker volume create wicked-waifus-postgres-vol

@ -0,0 +1 @@
Subproject commit 146c610632c8d9c3948c6a64ffc6cfe0258bcced

1
data/assets/game-data Submodule

@ -0,0 +1 @@
Subproject commit 902e7a8eae8b7a530c8dd38d5dc4b48dd808ad6c

View file

@ -4,3 +4,7 @@ http_addr = "0.0.0.0:10001"
[encryption]
key = "t+AEu5SGdpz06tomonajLMau9AJgmyTvVhz9VtGf1+0="
iv = "fprc5lBWADQB7tim0R2JxQ=="
[serve]
serve_web_path = "/"
serve_dir_path = "assets/config-server"

View file

@ -2,12 +2,12 @@ name: wicked-waifus-ps
services:
wicked-waifus-hotpatch-server:
image: wicked-waifus-hotpatch-server:1.4.0-SNAPSHOT
image: wicked-waifus-hotpatch-server:2.1.0-SNAPSHOT
depends_on:
wicked-waifus-postgres:
condition: service_healthy
ports:
- '10002:10002'
volumes:
- "./docker/hotpatch.toml:/app/hotpatch.toml"
- "./assets/hotpatch:/app/assets/hotpatch"
- "./data/docker/hotpatch.toml:/app/hotpatch.toml"
- "./data/assets/hotpatch-server:/app/assets/hotpatch"

View file

@ -2,26 +2,26 @@ name: wicked-waifus-ps
services:
wicked-waifus-config-server:
image: wicked-waifus-config-server:1.4.0-SNAPSHOT
image: wicked-waifus-config-server:2.1.0-SNAPSHOT
depends_on:
wicked-waifus-postgres:
condition: service_healthy
ports:
- '10001:10001'
volumes:
- "./docker/configserver.toml:/app/configserver.toml"
- "./assets/config:/app/assets/config"
- "./data/docker/configserver.toml:/app/configserver.toml"
- "./data/assets/config:/app/assets/config"
wicked-waifus-login-server:
image: wicked-waifus-login-server:1.4.0-SNAPSHOT
image: wicked-waifus-login-server:2.1.0-SNAPSHOT
depends_on:
wicked-waifus-postgres:
condition: service_healthy
ports:
- '5500:5500'
volumes:
- "./docker/loginserver.toml:/app/loginserver.toml"
- "./data/docker/loginserver.toml:/app/loginserver.toml"
wicked-waifus-gateway-server:
image: wicked-waifus-gateway-server:1.4.0-SNAPSHOT
image: wicked-waifus-gateway-server:2.1.0-SNAPSHOT
depends_on:
wicked-waifus-postgres:
condition: service_healthy
@ -30,9 +30,9 @@ services:
# - '10003:10003'
- '7777:7777/udp'
volumes:
- "./docker/gateway.toml:/app/gateway.toml"
- "./data/docker/gateway.toml:/app/gateway.toml"
wicked-waifus-game-server:
image: wicked-waifus-game-server:1.4.0-SNAPSHOT
image: wicked-waifus-game-server:2.1.0-SNAPSHOT
depends_on:
wicked-waifus-postgres:
condition: service_healthy
@ -40,8 +40,8 @@ services:
# ports:
# - '10004:10004'
volumes:
- "./docker/gameserver.toml:/app/gameserver.toml"
- "./assets/logic:/app/assets/logic"
- "./data/docker/gameserver.toml:/app/gameserver.toml"
- "./data/assets/game-data:/app/data/assets/game-data"
wicked-waifus-postgres:
image: postgres:16.4-alpine3.20
user: postgres
@ -56,7 +56,7 @@ services:
environment:
- "POSTGRES_PASSWORD=toor"
volumes:
- "./docker/postgres/scripts:/docker-entrypoint-initdb.d"
- "./data/docker/postgres/scripts:/docker-entrypoint-initdb.d"
- wicked-waifus-postgres-vol:/var/lib/postgresql/data
volumes:
wicked-waifus-postgres-vol:

View file

@ -1,28 +0,0 @@
[package]
name = "game-server"
edition = "2021"
version.workspace = true
[dependencies]
# Framework
tokio.workspace = true
# Serialization
serde.workspace = true
# Util
anyhow.workspace = true
thiserror.workspace = true
paste.workspace = true
dashmap.workspace = true
hex.workspace = true
# Tracing
tracing.workspace = true
# Internal
common.workspace = true
shorekeeper-data.workspace = true
shorekeeper-database.workspace = true
shorekeeper-network.workspace = true
shorekeeper-protocol.workspace = true

View file

@ -1,12 +0,0 @@
use shorekeeper_protocol::{GuideInfoRequest, GuideInfoResponse};
use crate::logic::player::Player;
pub fn on_guide_info_request(
_player: &Player,
_request: GuideInfoRequest,
response: &mut GuideInfoResponse,
) {
// TODO: Implement this
response.guide_group_finish_list = Vec::new();
}

View file

@ -1,31 +0,0 @@
use shorekeeper_protocol::{
ErrorCode, SceneLoadingFinishRequest, SceneLoadingFinishResponse, SceneTraceRequest,
SceneTraceResponse, UpdateSceneDateRequest, UpdateSceneDateResponse,
};
use crate::logic::player::Player;
pub fn on_scene_trace_request(
_player: &Player,
request: SceneTraceRequest,
_: &mut SceneTraceResponse,
) {
tracing::debug!("SceneTraceRequest: trace id {}", request.scene_trace_id);
}
pub fn on_scene_loading_finish_request(
_player: &Player,
_request: SceneLoadingFinishRequest,
response: &mut SceneLoadingFinishResponse,
) {
// TODO: Implement this if needed
response.error_code = ErrorCode::Success.into();
}
pub fn on_update_scene_date_request(
_player: &Player,
_request: UpdateSceneDateRequest,
response: &mut UpdateSceneDateResponse,
) {
response.error_code = ErrorCode::Success.into();
}

View file

@ -1,35 +0,0 @@
use crate::logic::ecs::component::ComponentContainer;
use shorekeeper_protocol::{
VisionExploreSkillSetRequest, VisionExploreSkillSetResponse, VisionSkillChangeNotify,
VisionSkillInformation,
};
use crate::{logic::player::Player, query_with};
pub fn on_vision_explore_skill_set_request(
player: &mut Player,
request: VisionExploreSkillSetRequest,
response: &mut VisionExploreSkillSetResponse,
) {
player.explore_tools.active_explore_skill = request.skill_id;
for (entity, owner, mut vision_skill) in query_with!(
player.world.borrow().get_world_entity(),
OwnerPlayer,
VisionSkill
) {
if owner.0 == player.basic_info.id {
vision_skill.skill_id = request.skill_id;
player.notify(VisionSkillChangeNotify {
entity_id: entity.into(),
vision_skill_infos: vec![VisionSkillInformation {
skill_id: request.skill_id,
..Default::default()
}],
..Default::default()
})
}
}
response.skill_id = request.skill_id;
}

View file

@ -1,41 +0,0 @@
const UE = require("ue"),
Info_1 = require("../../../Core/Common/Info"),
MathUtils_1 = require("../../../Core/Utils/MathUtils"),
EventDefine_1 = require("../../Common/Event/EventDefine"),
EventSystem_1 = require("../../Common/Event/EventSystem"),
UiControllerBase_1 = require("../../Ui/Base/UiControllerBase"),
UiLayerType_1 = require("../../Ui/Define/UiLayerType"),
UiLayer_1 = require("../../Ui/UiLayer");
var _a = require('../Module/WaterMask/WaterMaskController').WaterMaskView;
_a.LOo = 0.15;
_a.yOo = 700;
_a.IOo = 700;
_a.vOo = function () {
void 0 !== _a.SOo && _a.EOo();
var e = UiLayer_1.UiLayer.GetLayerRootUiItem(UiLayerType_1.ELayerType.WaterMask),
t = (_a.SOo = UE.KuroActorManager.SpawnActor(Info_1.Info.World, UE.UIContainerActor.StaticClass(),
MathUtils_1.MathUtils.DefaultTransform, void 0), _a.SOo.RootComponent),
e = (t.SetDisplayName("WaterMaskContainer"), UE.KuroStaticLibrary.SetActorPermanent(_a.SOo, !0, !0), _a.SOo
.K2_AttachRootComponentTo(e), t.GetRootCanvas().GetOwner().RootComponent),
i = e.widget.width % _a.yOo / 2,
r = e.widget.height % _a.IOo / 2,
n = e.widget.width / 2,
_ = e.widget.height / 2,
s = Math.ceil(e.widget.width / _a.yOo),
o = Math.ceil(e.widget.height / _a.IOo),
v = "NCSO @ discord.gg/reversedrooms";
for (let a = 0; a < s; a++)
for (let e = 0; e < o; e++) {
var E = UE.KuroActorManager.SpawnActor(Info_1.Info.World, UE.UITextActor.StaticClass(), MathUtils_1
.MathUtils.DefaultTransform, void 0),
U = E.RootComponent,
U = (E.K2_AttachRootComponentTo(t), U.SetDisplayName("WaterMaskText"), E.GetComponentByClass(UE
.UIText.StaticClass()));
U.SetFontSize(_a.vFt), U.SetOverflowType(0), U.SetAlpha(_a.LOo), U.SetFont(UE.LGUIFontData
.GetDefaultFont()), U.SetText(v), U.SetUIRelativeLocation(new UE.Vector(a * _a.yOo - n + i, e *
_a.IOo - _ + r, 0)), U.SetUIRelativeRotation(new UE.Rotator(0, _a.TOo, 0)), UE.KuroStaticLibrary
.SetActorPermanent(E, !0, !0)
}
};
_a.vOo();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6 MiB

After

Width:  |  Height:  |  Size: 7.7 MiB

View file

@ -1,56 +0,0 @@
use serde::Deserialize;
#[derive(Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct PropValueData {
pub id: i32,
pub value: f32,
pub is_ratio: bool,
}
#[derive(Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct VectorData([f32; 3]);
impl VectorData {
pub fn get_x(&self) -> f32 {
self.0[0]
}
pub fn get_y(&self) -> f32 {
self.0[1]
}
pub fn get_z(&self) -> f32 {
self.0[2]
}
}
#[derive(Deserialize, Clone)]
#[serde(rename_all = "PascalCase")]
pub struct RawVectorData {
pub x: f32,
pub y: f32,
pub z: f32,
}
impl RawVectorData {
pub fn get_x(&self) -> f32 {
self.x
}
pub fn get_y(&self) -> f32 {
self.y
}
pub fn get_z(&self) -> f32 {
self.z
}
}
#[derive(Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct EntranceEntityData {
pub dungeon_id: i32,
pub entrance_entity_id: i32,
}

View file

@ -1,191 +0,0 @@
use std::{
fs,
io::{self, BufRead},
path::Path,
};
use std::io::Write;
use quote::{format_ident, quote};
const CODEGEN_OUT_DIR: &str = "generated/";
pub fn main() {
let _ = fs::create_dir(CODEGEN_OUT_DIR);
let config_file = "proto/config.csv";
let config_path = Path::new("proto/config.csv");
if config_path.exists() {
println!("cargo:rerun-if-changed={config_file}");
impl_proto_config(config_path, Path::new("generated/proto_config.rs")).unwrap();
}
let proto_file = "proto/shorekeeper.proto";
if Path::new(&proto_file).exists() {
println!("cargo:rerun-if-changed={proto_file}");
prost_build::Config::new()
.out_dir(CODEGEN_OUT_DIR)
.default_package_filename("shorekeeper")
.type_attribute(".", "#[derive(shorekeeper_protocol_derive::MessageID)]")
.type_attribute(".", "#[derive(serde::Serialize, serde::Deserialize)]")
.compile_protos(&[proto_file], &["shorekeeper"])
.unwrap();
impl_dumper(Path::new("generated/shorekeeper.rs")).unwrap();
impl_message_id(Path::new("generated/shorekeeper.rs")).unwrap();
}
let proto_file = "proto/internal.proto";
if Path::new(&proto_file).exists() {
println!("cargo:rerun-if-changed={proto_file}");
prost_build::Config::new()
.out_dir(CODEGEN_OUT_DIR)
.type_attribute(".", "#[derive(shorekeeper_protocol_derive::MessageID)]")
.compile_protos(&[proto_file], &["internal"])
.unwrap();
impl_message_id(Path::new("generated/internal.rs")).unwrap();
}
let proto_file = "proto/data.proto";
if Path::new(&proto_file).exists() {
println!("cargo:rerun-if-changed={proto_file}");
prost_build::Config::new()
.out_dir(CODEGEN_OUT_DIR)
.compile_protos(&[proto_file], &["data"])
.unwrap();
}
}
pub fn impl_proto_config(csv_path: &Path, codegen_path: &Path) -> io::Result<()> {
let file = fs::File::open(csv_path)?;
let reader = io::BufReader::new(file);
let mut match_arms = quote! {};
for line in reader.lines() {
let line = line?;
let mut row = line.split(',');
let message_id = row.next().unwrap().parse::<u16>().unwrap();
let flags = row.next().unwrap().parse::<u8>().unwrap();
match_arms = quote! {
#match_arms
#message_id => MessageFlags(#flags),
}
}
let generated_code = quote! {
pub mod proto_config {
#[derive(Clone, Copy)]
pub struct MessageFlags(u8);
impl MessageFlags {
pub fn value(self) -> u8 {
self.0
}
}
pub fn get_message_flags(id: u16) -> MessageFlags {
match id {
#match_arms
_ => MessageFlags(0),
}
}
}
};
let syntax_tree = syn::parse2(generated_code).unwrap();
let formatted = prettyplease::unparse(&syntax_tree);
fs::write(codegen_path, formatted.as_bytes())?;
Ok(())
}
pub fn impl_message_id(path: &Path) -> io::Result<()> {
let file = fs::File::open(path)?;
let reader = io::BufReader::new(file);
let mut output = Vec::new();
let mut attr = None;
for line in reader.lines() {
let line = line?;
if line.contains("MessageId:") {
attr = Some(make_message_id_attr(&line).unwrap());
} else {
output.push(line);
if let Some(attr) = attr.take() {
output.push(attr);
}
}
}
fs::write(path, output.join("\n").as_bytes())?;
Ok(())
}
fn make_message_id_attr(line: &str) -> Option<String> {
let id = line.trim_start().split(' ').nth(2)?.parse::<u16>().ok()?;
Some(format!("#[message_id({id})]"))
}
pub fn impl_dumper(codegen_path: &Path) -> io::Result<()> {
let file = fs::File::open(codegen_path)?;
let reader = io::BufReader::new(file);
let mut match_arms = quote! {};
let mut id = None;
for line in reader.lines() {
let line = line?;
if line.contains("MessageId:") {
id = Some(
line.trim_start().split(' ').nth(2).unwrap().parse::<u16>().ok().unwrap()
);
} else if line.contains("pub struct") {
if let Some(id) = id.take() {
let name = line.trim_start().split(' ').nth(2).unwrap().to_string();
let name_ident = format_ident!("{}", name);
match_arms = quote! {
#match_arms
#id => Ok((#name, serde_json::to_string_pretty(&#name_ident::decode(data)?)?)),
};
}
}
}
let generated_code = quote! {
pub mod proto_dumper {
use prost::Message;
use crate::*;
use crate::ai::*;
use crate::combat_message::*;
use crate::debug::*;
use crate::summon::*;
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("serde_json::Error: {0}")]
Json(#[from] serde_json::Error),
#[error("serde_json::Error: {0}")]
Decode(#[from] prost::DecodeError),
}
pub fn get_debug_info(id: u16, data: &[u8]) -> Result<(&str, String), Error> {
match id {
#match_arms
_ => Ok(("UnknownType", "".to_string())),
}
}
}
};
let syntax_tree = syn::parse2(generated_code).unwrap();
let formatted = prettyplease::unparse(&syntax_tree);
let mut file = fs::OpenOptions::new().append(true).open(codegen_path)?;
file.write(formatted.as_bytes())?;
Ok(())
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,12 +0,0 @@
[package]
name = "shorekeeper-protocol-derive"
version = "0.1.0"
edition = "2021"
[dependencies]
syn = "2.0.53"
quote = "1.0.35"
proc-macro2 = "1.0.79"
[lib]
proc-macro = true

View file

@ -1,27 +0,0 @@
use proc_macro::TokenStream;
use quote::{quote, ToTokens};
use syn::{parse_macro_input, DeriveInput, Meta, MetaList};
#[proc_macro_derive(MessageID, attributes(message_id))]
pub fn message_id_derive(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let struct_name = input.ident;
let id = match input
.attrs
.iter()
.find(|attr| attr.path().is_ident("message_id"))
{
Some(attr) => match attr.meta {
Meta::List(MetaList { ref tokens, .. }) => tokens.into_token_stream(),
_ => panic!("Invalid message_id attribute value"),
},
_ => 0u16.into_token_stream(),
};
TokenStream::from(quote! {
impl crate::MessageID for #struct_name {
const MESSAGE_ID: u16 = #id;
}
})
}

View file

@ -1,36 +0,0 @@
include!("../generated/proto_config.rs");
include!("../generated/data.rs");
include!("../generated/shorekeeper.rs");
include!("../generated/internal.rs");
pub mod message;
pub use prost::DecodeError as ProtobufDecodeError;
pub use prost::Message as Protobuf;
pub trait MessageID {
const MESSAGE_ID: u16;
fn get_message_id(&self) -> u16 {
Self::MESSAGE_ID
}
}
pub trait ProtocolUnit: Protobuf + MessageID {}
impl<T: Protobuf + MessageID> ProtocolUnit for T {}
#[derive(Debug, PartialEq)]
pub enum MessageRoute {
None,
Gateway,
GameServer,
}
impl From<proto_config::MessageFlags> for MessageRoute {
fn from(flags: proto_config::MessageFlags) -> Self {
match flags.value() & 3 {
0 => Self::Gateway,
2 => Self::GameServer,
_ => Self::None,
}
}
}

View file

@ -1,198 +0,0 @@
use byteorder::{ReadBytesExt, WriteBytesExt, LE};
use std::io::{self, Read, Write};
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("IO Error: {0}")]
Io(#[from] io::Error),
#[error("Invalid message type: {0}")]
InvalidMessageType(u8),
#[error("Checksum mismatch, received: {0}, calculated: {1}")]
InvalidChecksum(u32, u32),
}
#[derive(Debug)]
pub enum Message {
Request {
sequence_number: u32,
rpc_id: u16,
message_id: u16,
payload: Option<Box<[u8]>>,
},
Response {
sequence_number: u32,
rpc_id: u16,
message_id: u16,
payload: Option<Box<[u8]>>,
},
Push {
sequence_number: u32,
message_id: u16,
payload: Option<Box<[u8]>>,
},
}
impl Message {
const TYPE_REQUEST: u8 = 1;
const TYPE_RESPONSE: u8 = 2;
const TYPE_PUSH: u8 = 4;
pub fn encode(&self, out: &mut [u8]) -> io::Result<()> {
let mut w = io::Cursor::new(out);
let (sequence_number, message_id, payload) = match self {
Self::Request {
sequence_number,
message_id,
payload,
..
}
| Self::Response {
sequence_number,
message_id,
payload,
..
}
| Self::Push {
sequence_number,
message_id,
payload,
} => (sequence_number, message_id, payload),
};
w.write_u8(self.get_message_type())?;
w.write_u32::<LE>(*sequence_number)?;
match self {
Self::Request { rpc_id, .. } | Self::Response { rpc_id, .. } => {
w.write_u16::<LE>(*rpc_id)?
}
_ => (),
}
w.write_u16::<LE>(*message_id)?;
if let Some(payload) = payload.as_ref() {
w.write_u32::<LE>(crc32fast::hash(payload))?;
w.write_all(payload)?;
} else {
w.write_u32::<LE>(0)?;
}
Ok(())
}
pub fn decode(src: &[u8]) -> Result<Self, Error> {
let mut r = io::Cursor::new(src);
let message_type = r.read_u8()?;
let sequence_number = r.read_u32::<LE>()?;
let rpc_id = match message_type {
Self::TYPE_REQUEST | Self::TYPE_RESPONSE => r.read_u16::<LE>()?,
_ => 0,
};
let message_id = r.read_u16::<LE>()?;
let recv_crc = r.read_u32::<LE>()?;
let mut payload = vec![0u8; src.len() - r.position() as usize].into_boxed_slice();
let _ = r.read(&mut payload)?;
let calc_crc = crc32fast::hash(&payload);
(recv_crc == calc_crc)
.then_some(())
.ok_or(Error::InvalidChecksum(recv_crc, calc_crc))?;
let msg = match message_type {
Self::TYPE_REQUEST => Self::Request {
sequence_number,
rpc_id,
message_id,
payload: Some(payload),
},
Self::TYPE_RESPONSE => Self::Response {
sequence_number,
rpc_id,
message_id,
payload: Some(payload),
},
Self::TYPE_PUSH => Self::Push {
sequence_number,
message_id,
payload: Some(payload),
},
_ => return Err(Error::InvalidMessageType(message_type)),
};
Ok(msg)
}
pub fn get_encoding_length(&self) -> usize {
match self {
Self::Request { payload, .. } | Self::Response { payload, .. } => {
13 + payload.as_ref().map(|p| p.len()).unwrap_or_default()
}
Self::Push { payload, .. } => {
11 + payload.as_ref().map(|p| p.len()).unwrap_or_default()
}
}
}
pub fn get_message_type(&self) -> u8 {
match self {
Self::Request { .. } => Self::TYPE_REQUEST,
Self::Response { .. } => Self::TYPE_RESPONSE,
Self::Push { .. } => Self::TYPE_PUSH,
}
}
pub fn is_request(&self) -> bool {
matches!(self, Self::Request { .. })
}
pub fn is_push(&self) -> bool {
matches!(self, Self::Push { .. })
}
pub fn get_message_id(&self) -> u16 {
match self {
Self::Request { message_id, .. }
| Self::Response { message_id, .. }
| Self::Push { message_id, .. } => *message_id,
}
}
pub fn get_rpc_id(&self) -> u16 {
match self {
Self::Request { rpc_id, .. } | Self::Response { rpc_id, .. } => *rpc_id,
_ => 0,
}
}
pub fn remove_payload(&mut self) -> Box<[u8]> {
match self {
Self::Request { payload, .. }
| Self::Response { payload, .. }
| Self::Push { payload, .. } => payload.take().unwrap_or_else(|| Box::new([0u8; 0])),
}
}
pub fn set_payload(&mut self, new_payload: Box<[u8]>) {
match self {
Self::Request { payload, .. }
| Self::Response { payload, .. }
| Self::Push { payload, .. } => *payload = Some(new_payload),
}
}
pub fn get_sequence_number(&self) -> u32 {
match self {
Self::Request {
sequence_number, ..
}
| Self::Response {
sequence_number, ..
}
| Self::Push {
sequence_number, ..
} => *sequence_number,
}
}
}

View file

@ -1,5 +1,5 @@
[package]
name = "common"
name = "wicked-waifus-commons"
edition = "2021"
version.workspace = true

View file

@ -1,12 +1,11 @@
[package]
name = "config-server"
name = "wicked-waifus-config-server"
edition = "2021"
version.workspace = true
[dependencies]
# Framework
tokio.workspace = true
shorekeeper-http.workspace = true
# Serialization
serde.workspace = true
@ -19,4 +18,5 @@ anyhow.workspace = true
tracing.workspace = true
# Internal
common.workspace = true
wicked-waifus-commons.workspace = true
wicked-waifus-http.workspace = true

View file

@ -4,3 +4,7 @@ http_addr = "0.0.0.0:10001"
[encryption]
key = "t+AEu5SGdpz06tomonajLMau9AJgmyTvVhz9VtGf1+0="
iv = "fprc5lBWADQB7tim0R2JxQ=="
[serve]
serve_web_path = "/"
serve_dir_path = "data/assets/config-server"

View file

@ -1,18 +1,25 @@
use std::sync::LazyLock;
use anyhow::Result;
use common::config_util::{self, TomlConfig};
use serde::Deserialize;
use shorekeeper_http::{
config::{AesSettings, NetworkSettings},
use wicked_waifus_commons::config_util::{self, TomlConfig};
use wicked_waifus_http::{
Application,
config::{AesSettings, NetworkSettings},
};
#[derive(Deserialize)]
pub struct ServeConfig {
pub serve_web_path: String,
pub serve_dir_path: String,
}
#[derive(Deserialize)]
pub struct ServerConfig {
pub network: NetworkSettings,
pub encryption: AesSettings,
pub serve: ServeConfig,
}
impl TomlConfig for ServerConfig {
@ -24,11 +31,17 @@ async fn main() -> Result<()> {
static CONFIG: LazyLock<ServerConfig> =
LazyLock::new(|| config_util::load_or_create("configserver.toml"));
::common::splash::print_splash();
::common::logging::init_axum(::tracing::Level::DEBUG);
::wicked_waifus_commons::splash::print_splash();
::wicked_waifus_commons::logging::init_axum(::tracing::Level::DEBUG);
tracing::debug!(
"Serving files from {} at {}",
&CONFIG.serve.serve_web_path,
&CONFIG.serve.serve_dir_path
);
Application::new()
.serve_dir("/", "assets/config")
.serve_dir(&CONFIG.serve.serve_web_path, &CONFIG.serve.serve_dir_path)
.with_encryption(&CONFIG.encryption)
.with_logger()
.serve(&CONFIG.network)

View file

@ -1,10 +1,11 @@
[package]
name = "shorekeeper-data"
name = "wicked-waifus-data"
edition = "2021"
version.workspace = true
[dependencies]
serde.workspace = true
serde_json.workspace = true
serde_repr.workspace = true
paste.workspace = true
thiserror.workspace = true

View file

@ -0,0 +1,15 @@
use std::collections::HashMap;
use serde::Deserialize;
#[derive(Debug, Deserialize, Clone)]
#[serde(rename_all = "PascalCase")]
pub struct AdventureTaskData {
pub id: i32,
pub chapter_id: i32,
pub task_text: String,
pub record_id: Vec<i32>,
pub need_progress: i32,
pub drop_ids: i32,
pub path_id: i32,
pub jump_to: HashMap<String, String>,
}

View file

@ -0,0 +1,30 @@
use std::collections::HashMap;
use serde::Deserialize;
#[derive(Debug, Deserialize, Clone)]
#[serde(rename_all = "PascalCase")]
pub struct AreaData {
pub area_id: i32,
pub level: i32,
pub country_id: i32,
pub delivery_mark_id: i32,
pub area_name: String,
pub map_config_id: i32,
pub title: String,
pub father: i32,
pub tag: Vec<i32>,
pub record: i32,
pub tips: i32,
pub is_init_actived: bool,
#[serde(rename = "WorldMonsterLevelMax")]
pub world_monster_level_max: HashMap<i32, i32>,
#[serde(rename = "WuYinQuID")]
pub wu_yin_qu_id: i32,
pub state_id: i32,
pub atmosphere_id: i32,
pub edge_wall_name: String,
pub delivery_mark_type: i32,
pub sort_index: i32,
pub enter_area_tags: HashMap<String, i32>,
pub leave_area_tags: HashMap<String, i32>,
}

View file

@ -0,0 +1,12 @@
use serde::Deserialize;
#[derive(Debug, Deserialize, Clone)]
#[serde(rename_all = "PascalCase")]
pub struct DragonPoolData {
pub id: i32,
pub core_id: i32,
pub goal: Vec<i32>,
pub drop_ids: Vec<i32>,
pub dark_coast_delivery_list: Vec<i32>,
pub auto_take: bool,
}

View file

@ -0,0 +1,9 @@
use serde::Deserialize;
#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct GachaData {
pub id: i32,
pub rule_group_id: i32,
pub sort: i32,
}

View file

@ -0,0 +1,9 @@
use serde::Deserialize;
#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct GachaPoolData {
pub id: i32,
pub gacha_id: i32,
pub sort: i32,
}

View file

@ -0,0 +1,22 @@
use serde::Deserialize;
use crate::GachaViewTypeInfoId;
#[derive(Debug, Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct GachaViewInfoData {
pub id: i32,
pub r#type: GachaViewTypeInfoId,
pub summary_title: String,
pub summary_describe: String,
// TODO: Effect path
pub theme_color: String,
pub content_texture_path: String,
pub content_texture_bg_path: String,
pub under_bg_texture_path: String,
pub tag_not_selected_sprite_path: String,
pub tag_selected_sprite_path: String,
pub weapon_prefab_path: String,
pub up_list: Vec<i32>,
pub show_id_list: Vec<i32>,
pub preview_id_list: Vec<i32>,
}

View file

@ -0,0 +1,11 @@
use serde::Deserialize;
#[derive(Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct GuideTutorialData {
pub id: i32,
pub tutorial_type: i32,
pub tutorial_order: i32,
pub page_id: Vec<i32>,
pub tutorial_tip: bool,
}

View file

@ -1,7 +1,7 @@
use serde::Deserialize;
use crate::RawVectorData;
use crate::{ComponentsData, RawVectorData};
#[derive(Deserialize, Clone)]
#[derive(Deserialize, Clone, Debug)]
#[serde(rename_all = "PascalCase")]
pub struct LevelEntityConfigData {
pub id: i32,
@ -13,6 +13,5 @@ pub struct LevelEntityConfigData {
pub is_hidden: bool,
pub area_id: i32,
pub transform: Vec<RawVectorData>,
// Schemaless property, any suggestions @xeondev??
pub components_data: serde_json::Value,
pub components_data: ComponentsData,
}

View file

@ -42,7 +42,7 @@ macro_rules! json_data {
}
macro_rules! json_hash_table_data {
($($table_type:ident, $key_param:expr;)*) => {
($($table_type:ident, $key_param:expr, $key_type:ty;)*) => {
$(paste! {
mod [<$table_type:snake>];
pub use [<$table_type:snake>]::[<$table_type Data>];
@ -54,11 +54,15 @@ macro_rules! json_hash_table_data {
use std::sync::OnceLock;
pub(crate) type Data = super::[<$table_type Data>];
pub(crate) static TABLE: OnceLock<HashMap<i64, Data>> = OnceLock::new();
pub(crate) static TABLE: OnceLock<HashMap<$key_type, Data>> = OnceLock::new();
pub fn iter() -> std::collections::hash_map::Iter<'static, i64, Data> {
pub fn iter() -> std::collections::hash_map::Iter<'static, $key_type, Data> {
TABLE.get().unwrap().iter()
}
pub fn get(k: &$key_type) -> Option<&Data> {
TABLE.get().unwrap().get(k)
}
}
})*
@ -86,14 +90,86 @@ pub fn load_all_json_data(base_path: &str) -> Result<(), LoadDataError> {
}
json_data! {
RoleInfo;
WeaponConf;
AdventureTask;
Area;
BaseProperty;
InstanceDungeon;
FunctionCondition;
ExploreTools;
FunctionCondition;
Gacha;
GachaPool;
GachaViewInfo;
GuideTutorial;
InstanceDungeon;
LordGym;
RoleInfo;
Teleporter;
WeaponConf;
}
json_hash_table_data! {
LevelEntityConfig, entity_id;
DragonPool, id, i32;
LevelEntityConfig, entity_id, i64;
// TemplateConfig, blueprint_type, String;
}
mod textmap;
pub mod text_map_data {
use std::collections::HashMap;
use std::sync::OnceLock;
use crate::LoadDataError;
use crate::textmap::TextMapData;
static EMPTY: OnceLock<HashMap<String, String>> = OnceLock::new();
static TABLE: OnceLock<HashMap<String, HashMap<String, String>>> = OnceLock::new();
pub fn load_textmaps(base_path: &str) -> Result<(), LoadDataError> {
let _ = EMPTY.set(HashMap::new());
let languages = std::fs::read_dir(base_path)?
.filter_map(|entry| entry.ok())
.filter(|entry| entry.path().is_dir())
.collect::<Vec<_>>();
let mut result: HashMap<String, HashMap<String, String>> = HashMap::new();
for language in languages {
let lang_id = language.file_name().to_str().unwrap().to_string();
let json_content = std::fs::read_to_string(
&format!("{base_path}/{lang_id}/multi_text/MultiText.json")
)?;
result.insert(
lang_id,
serde_json::from_str::<Vec<TextMapData>>(&json_content)?
.iter()
.cloned()
.map(|element| (element.id, element.content))
.collect::<HashMap<_, _>>(),
);
}
let _ = TABLE.set(result);
Ok(())
}
pub fn get_textmap(language: i32) -> &'static HashMap<String, String> {
let (text_code, _audio_code) = get_language_from_i32(language);
TABLE.get().unwrap().get(text_code).unwrap_or(EMPTY.get().unwrap())
}
fn get_language_from_i32(language: i32) -> (&'static str, &'static str) {
match language {
0 => ("zh-Hans", "zh"),
1 => ("en", "en"),
2 => ("ja", "ja"),
3 => ("ko", "ko"),
4 => ("ru", "en"),
5 => ("zh-Hant", "zh"),
6 => ("de", "en"),
7 => ("es", "en"),
8 => ("pt", "en"),
9 => ("id", "en"),
10 => ("fr", "en"),
11 => ("vi", "en"),
12 => ("th", "en"),
_ => ("en", "en"),
}
}
}

View file

@ -0,0 +1,20 @@
use serde::Deserialize;
#[derive(Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct LordGymData {
pub id: i32,
pub difficulty: i32,
pub reward_id: i32,
pub play_id: i32,
pub gym_title: String,
pub icon_path: String,
pub play_description: String,
pub help_id: i32,
pub monster_list: Vec<i32>,
pub monster_level: i32,
pub lock_con: i32,
pub lock_description: String,
pub filter_type: i32,
pub is_debug: bool,
}

View file

@ -0,0 +1,252 @@
use serde::Deserialize;
use serde_repr::Deserialize_repr;
#[derive(Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct PropValueData {
pub id: i32,
pub value: f32,
pub is_ratio: bool,
}
#[derive(Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct VectorData([f32; 3]);
impl VectorData {
pub fn get_x(&self) -> f32 {
self.0[0]
}
pub fn get_y(&self) -> f32 {
self.0[1]
}
pub fn get_z(&self) -> f32 {
self.0[2]
}
}
#[derive(Deserialize, Clone, Debug)]
#[serde(rename_all = "PascalCase")]
pub struct RawVectorData {
pub x: f32,
pub y: f32,
pub z: f32,
}
impl RawVectorData {
pub fn get_x(&self) -> f32 {
self.x
}
pub fn get_y(&self) -> f32 {
self.y
}
pub fn get_z(&self) -> f32 {
self.z
}
}
#[derive(Deserialize)]
#[serde(rename_all = "PascalCase")]
pub struct EntranceEntityData {
pub dungeon_id: i32,
pub entrance_entity_id: i32,
}
#[derive(Deserialize_repr, PartialEq, Debug, Copy, Clone)]
#[repr(i32)]
pub enum GachaViewTypeInfoId {
NoviceConvene = 1,
FeaturedResonatorConvene = 2,
FeaturedWeaponConvene = 3,
StandardResonatorConvene = 4,
StandardWeaponConvene = 5,
BeginnersChoiceConvene = 6,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "PascalCase")]
pub struct Category {
pub main_type: Option<String>,
pub monster_match_type: Option<i32>,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "PascalCase")]
pub struct ScanFunction {
pub scan_id: Option<i32>,
pub is_concealed: Option<bool>,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "PascalCase")]
pub struct WorldLevelBonusType {
pub r#type: Option<i32>,
pub world_level_bonus_id: Option<i32>,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "PascalCase")]
pub struct BaseInfoComponent {
pub tid_name: Option<String>,
pub category: Option<Category>,
pub camp: Option<i32>,
pub online_interact_type: Option<i32>,
pub scan_function: Option<ScanFunction>,
pub aoi_layer: Option<i32>,
pub entity_property_id: Option<i32>,
pub focus_priority: Option<i32>,
pub aoi_zradius: Option<i32>,
// TODO: Add more
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "PascalCase")]
pub struct AiComponent {
pub disabled: Option<bool>,
pub ai_id: Option<i32>,
// TODO: Add more
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "PascalCase")]
pub struct AttributeComponent {
pub property_id: Option<i32>,
pub level: Option<i32>,
pub world_level_bonus_type: Option<WorldLevelBonusType>,
pub rage_mode_id: Option<i32>,
pub hardness_mode_id: Option<i32>,
pub monster_prop_extra_rate_id: Option<i32>,
pub world_level_bonus_id: Option<i32>,
pub fight_music: Option<String>,
// TODO: Add more
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "PascalCase")]
pub struct TeleportPosition {
pub x: Option<f32>,
pub y: Option<f32>,
pub z: Option<f32>,
pub a: Option<f32>,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "PascalCase")]
pub struct TeleportComponent {
pub disabled: Option<bool>,
pub teleporter_id: Option<i32>,
#[serde(rename = "TeleportPos")]
pub teleport_position: Option<TeleportPosition>,
}
#[derive(Deserialize, Debug, Clone)]
#[serde(rename_all = "PascalCase")]
pub struct ComponentsData {
pub base_info_component: Option<BaseInfoComponent>,
pub ai_component: Option<AiComponent>,
pub attribute_component: Option<AttributeComponent>,
pub teleport_component: Option<TeleportComponent>,
// TODO: Implement this ones
pub scene_actor_ref_component: Option<serde_json::Value>,
pub effect_area_component: Option<serde_json::Value>,
pub entity_state_component: Option<serde_json::Value>,
pub condition_listener_component: Option<serde_json::Value>,
pub interact_component: Option<serde_json::Value>,
pub npc_perform_component: Option<serde_json::Value>,
pub var_component: Option<serde_json::Value>,
pub entity_visible_component: Option<serde_json::Value>,
pub level_ai_component: Option<serde_json::Value>,
pub trigger_component: Option<serde_json::Value>,
pub range_component: Option<serde_json::Value>,
pub spline_component: Option<serde_json::Value>,
pub bubble_component: Option<serde_json::Value>,
pub reward_component: Option<serde_json::Value>,
pub refresh_component: Option<serde_json::Value>,
pub passerby_npc_spawn_component: Option<serde_json::Value>,
pub vision_capture_component: Option<serde_json::Value>,
pub refresh_group_component: Option<serde_json::Value>,
pub collect_component: Option<serde_json::Value>,
pub target_gear_component: Option<serde_json::Value>,
pub fight_interact_component: Option<serde_json::Value>,
pub guide_line_creator_component: Option<serde_json::Value>,
pub photo_target_component: Option<serde_json::Value>,
pub model_component: Option<serde_json::Value>,
pub entity_group_component: Option<serde_json::Value>,
pub scene_item_life_cycle_component: Option<serde_json::Value>,
pub entity_state_audio_component: Option<serde_json::Value>,
pub animal_component: Option<serde_json::Value>,
pub monster_component: Option<serde_json::Value>,
pub nearby_tracking_component: Option<serde_json::Value>,
pub follow_track_component: Option<serde_json::Value>,
pub jigsaw_foundation: Option<serde_json::Value>,
pub treasure_box_component: Option<serde_json::Value>,
pub hook_lock_point: Option<serde_json::Value>,
pub explore_skill_interact_component: Option<serde_json::Value>,
pub attach_target_component: Option<serde_json::Value>,
pub target_gear_group_component: Option<serde_json::Value>,
pub spawn_monster_component: Option<serde_json::Value>,
pub skybox_component: Option<serde_json::Value>,
pub destructible_item: Option<serde_json::Value>,
pub fan_component: Option<serde_json::Value>,
pub state_hint_component: Option<serde_json::Value>,
pub buff_consumer_component: Option<serde_json::Value>,
pub reset_entities_pos_component: Option<serde_json::Value>,
pub group_ai_component: Option<serde_json::Value>,
pub pulling_object_foundation: Option<serde_json::Value>,
pub lift_component: Option<serde_json::Value>,
pub scene_item_movement_component: Option<serde_json::Value>,
pub reset_self_pos_component: Option<serde_json::Value>,
pub jigsaw_item: Option<serde_json::Value>,
pub level_play_component: Option<serde_json::Value>,
pub interact_gear_component: Option<serde_json::Value>,
pub ai_gear_strategy_component: Option<serde_json::Value>,
pub pick_interact_component: Option<serde_json::Value>,
pub level_sequence_frame_event_component: Option<serde_json::Value>,
pub air_wall_spawner_component: Option<serde_json::Value>,
pub progress_bar_control_component: Option<serde_json::Value>,
pub batch_bullet_caster_component: Option<serde_json::Value>,
pub client_trigger_component: Option<serde_json::Value>,
pub enrichment_area_component: Option<serde_json::Value>,
pub vehicle_component: Option<serde_json::Value>,
pub item_foundation2: Option<serde_json::Value>,
pub tele_control2: Option<serde_json::Value>,
pub interact_audio_component: Option<serde_json::Value>,
pub level_qte_component: Option<serde_json::Value>,
pub resurrection_component: Option<serde_json::Value>,
pub ai_alert_notify_component: Option<serde_json::Value>,
pub trample_component: Option<serde_json::Value>,
pub dungeon_entry_component: Option<serde_json::Value>,
pub level_prefab_perform_component: Option<serde_json::Value>,
pub render_specified_range_component: Option<serde_json::Value>,
pub walking_pattern_component: Option<serde_json::Value>,
pub no_render_portal_component: Option<serde_json::Value>,
pub adsorb_component: Option<serde_json::Value>,
pub beam_cast_component: Option<serde_json::Value>,
pub beam_receive_component: Option<serde_json::Value>,
pub timeline_track_control_component: Option<serde_json::Value>,
pub scene_bullet_component: Option<serde_json::Value>,
pub edit_custom_aoi_component: Option<serde_json::Value>,
pub combat_component: Option<serde_json::Value>,
pub location_safety_component: Option<serde_json::Value>,
pub turntable_control_component: Option<serde_json::Value>,
pub scene_item_ai_component: Option<serde_json::Value>,
pub buff_producer_component: Option<serde_json::Value>,
pub portal_component: Option<serde_json::Value>,
pub inhalation_ability_component: Option<serde_json::Value>,
pub inhaled_item_component: Option<serde_json::Value>,
pub monster_gacha_base_component: Option<serde_json::Value>,
pub monster_gacha_item_component: Option<serde_json::Value>,
pub time_stop_component: Option<serde_json::Value>,
pub hit_component: Option<serde_json::Value>,
pub levitate_magnet_component: Option<serde_json::Value>,
pub rebound_component: Option<serde_json::Value>,
pub rotator_component2: Option<serde_json::Value>,
pub conveyor_belt_component: Option<serde_json::Value>,
pub dynamic_portal_creator_component: Option<serde_json::Value>,
pub connector_component: Option<serde_json::Value>,
pub monitor_component: Option<serde_json::Value>,
}

View file

@ -17,6 +17,7 @@ pub struct RoleInfoData {
pub priority: i32,
pub show_property: Vec<i32>,
pub element_id: i32,
pub skin_id: i32,
pub spillover_item: HashMap<i32, i32>,
pub breach_model: i32,
pub special_energy_bar_id: i32,

View file

@ -0,0 +1,17 @@
use serde::Deserialize;
#[derive(Debug, Deserialize, Clone)]
#[serde(rename_all = "PascalCase")]
pub struct TeleporterData {
pub id: i32,
pub map_id: i32,
pub object_id: i32,
pub area_id: i32,
pub fog_id: i32,
pub r#type: i32,
pub teleport_entity_config_id: i64,
pub plot: String,
pub after_network_action: i32,
pub show_world_map: bool,
}

View file

@ -0,0 +1,11 @@
use serde::Deserialize;
use crate::ComponentsData;
#[derive(Debug, Deserialize, Clone)]
#[serde(rename_all = "PascalCase")]
pub struct TemplateConfigData {
pub id: i32,
pub blueprint_type: String,
pub name: String,
pub components_data: ComponentsData,
}

View file

@ -0,0 +1,8 @@
use serde::Deserialize;
#[derive(Deserialize, Clone)]
#[serde(rename_all = "PascalCase")]
pub struct TextMapData {
pub id: String,
pub content: String,
}

View file

@ -1,5 +1,5 @@
[package]
name = "shorekeeper-database"
name = "wicked-waifus-database"
edition = "2021"
version.workspace = true

View file

@ -0,0 +1,34 @@
[package]
name = "wicked-waifus-game-server"
edition = "2021"
version.workspace = true
[dependencies]
# Framework
tokio.workspace = true
# Serialization
serde.workspace = true
# Util
uuid = { version = "1.11.0", features = ["v4"] }
rand = "0.9.0-alpha.2"
# Used for debug
#serde_json = "1.0.135"
anyhow.workspace = true
thiserror.workspace = true
paste.workspace = true
dashmap.workspace = true
hex.workspace = true
# Tracing
tracing.workspace = true
# Internal
wicked-waifus-commons.workspace = true
wicked-waifus-data.workspace = true
wicked-waifus-database.workspace = true
wicked-waifus-network.workspace = true
wicked-waifus-protocol-internal.workspace = true
wicked-waifus-protocol.workspace = true

View file

@ -0,0 +1 @@
require('../Module/WaterMask/WaterMaskController').WaterMaskView.EOo();

View file

@ -1,7 +1,8 @@
use common::config_util::TomlConfig;
use serde::Deserialize;
use shorekeeper_database::DatabaseSettings;
use shorekeeper_network::config::ServiceEndPoint;
use wicked_waifus_commons::config_util::TomlConfig;
use wicked_waifus_database::DatabaseSettings;
use wicked_waifus_network::config::ServiceEndPoint;
#[derive(Deserialize)]
pub struct ServiceConfig {

View file

@ -1,6 +1,6 @@
use std::sync::OnceLock;
use shorekeeper_network::{config::ServiceEndPoint, ServiceClient, ServiceMessage};
use wicked_waifus_network::{config::ServiceEndPoint, ServiceClient, ServiceMessage};
static CLIENT: OnceLock<ServiceClient> = OnceLock::new();

Some files were not shown because too many files have changed in this diff Show more