mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-04-01 21:43:08 +02:00
Merge branch 'main' into feature/quest-enum
# Conflicts: # server/channelserver/handlers_quest.go
This commit is contained in:
4
.github/workflows/go.yml
vendored
4
.github/workflows/go.yml
vendored
@@ -27,7 +27,7 @@ jobs:
|
|||||||
./www/
|
./www/
|
||||||
./savedata/
|
./savedata/
|
||||||
./bin/
|
./bin/
|
||||||
./RoadShopItems.csv
|
./bundled-schema/
|
||||||
|
|
||||||
- name: Build Windows-amd64
|
- name: Build Windows-amd64
|
||||||
run: env GOOS=windows GOARCH=amd64 go build -v
|
run: env GOOS=windows GOARCH=amd64 go build -v
|
||||||
@@ -42,4 +42,4 @@ jobs:
|
|||||||
./www/
|
./www/
|
||||||
./savedata/
|
./savedata/
|
||||||
./bin/
|
./bin/
|
||||||
./RoadShopItems.csv
|
./bundled-schema/
|
||||||
|
|||||||
22
README.md
22
README.md
@@ -1,8 +1,18 @@
|
|||||||
# Erupe Community Edition
|
# Erupe Community Edition
|
||||||
|
## Setup
|
||||||
|
- If you are only looking to install Erupe, please use [a pre-compiled binary](https://github.com/ZeruLight/Erupe/releases/latest).
|
||||||
|
- If you want to modify or compile Erupe yourself please read on.
|
||||||
|
### Requirements
|
||||||
|
- [Go](https://go.dev/dl/)
|
||||||
|
- [PostgreSQL](https://www.postgresql.org/download/)
|
||||||
|
### Installation
|
||||||
|
1. Bring up a fresh database by using the [backup file attached with the latest release](https://github.com/ZeruLight/Erupe/releases/latest/download/Erupe.sql).
|
||||||
|
2. Run each script under [patch-schema](./patch-schema) as they introduce newer schema.
|
||||||
|
3. Edit [config.json](./config.json) such that the database password matches your PostgreSQL setup.
|
||||||
|
4. Run `go build` or `go run .` to compile Erupe.
|
||||||
|
### Note
|
||||||
|
- You will need to acquire and install the client files and quest binaries separately.
|
||||||
|
# Resources
|
||||||
|
[Community FAQ Pastebin](https://pastebin.com/QqAwZSTC)
|
||||||
|
|
||||||
This is a community upload of a community project. The amount of people who worked on it is innumerous, and hard to keep track of. Credits to Andoryuuta, Fist's Team, the French Team, Mai's Team and many others. No matter the relations, these files will remain public and open source, free for all to use and modify.
|
[Quests and Scenario Binary Files](https://github.com/xl3lackout/MHFZ-Quest-Files)
|
||||||
|
|
||||||
[A pastebin with various links, tips, and FAQ](https://pastebin.com/QqAwZSTC)
|
|
||||||
|
|
||||||
[An upload for the quest and scenario files exists here](https://github.com/xl3lackout/MHFZ-Quest-Files)
|
|
||||||
(Over 300k+ files)
|
|
||||||
|
|||||||
@@ -1,911 +0,0 @@
|
|||||||
10,6,1,2146,25,1,0,0,1,1,0,1,0,0
|
|
||||||
10,6,2,2147,25,1,0,0,1,1,0,1,0,0
|
|
||||||
10,6,3,2148,25,1,0,0,1,1,0,1,0,0
|
|
||||||
10,6,4,2149,25,1,0,0,1,1,0,1,0,0
|
|
||||||
10,6,5,2150,25,1,0,0,1,1,0,1,0,0
|
|
||||||
10,6,6,2151,25,1,0,0,1,1,0,1,0,0
|
|
||||||
10,6,7,2152,25,1,0,0,1,1,0,1,0,0
|
|
||||||
10,6,8,2153,25,1,0,0,1,1,0,1,0,0
|
|
||||||
10,6,9,2154,25,1,0,0,1,1,0,1,0,0
|
|
||||||
10,6,10,2155,25,1,0,0,1,1,0,1,0,0
|
|
||||||
10,6,11,4398,25,1,0,0,1,1,0,1,0,0
|
|
||||||
10,6,12,12460,25,1,0,0,1,1,0,1,0,0
|
|
||||||
10,6,13,12461,25,1,0,0,1,1,0,1,0,0
|
|
||||||
10,6,14,12462,25,1,0,0,1,1,0,1,0,0
|
|
||||||
10,6,15,12463,25,1,0,0,1,1,0,1,0,0
|
|
||||||
10,6,16,12464,25,1,0,0,1,1,0,1,0,0
|
|
||||||
10,6,17,12465,25,1,0,0,1,1,0,1,0,0
|
|
||||||
10,6,18,12466,25,1,0,0,1,1,0,1,0,0
|
|
||||||
10,6,19,12467,25,1,0,0,1,1,0,1,0,0
|
|
||||||
10,6,20,12468,25,1,0,0,1,1,0,1,0,0
|
|
||||||
10,6,21,12469,25,1,0,0,1,1,0,1,0,0
|
|
||||||
10,6,22,15109,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,6,23,15110,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,6,24,2158,200,100,0,0,1,1,0,1,0,0
|
|
||||||
10,6,25,12306,2,1,0,0,1,1,0,1,80,0
|
|
||||||
10,6,26,12306,20000,10000,0,0,1,1,0,1,80,0
|
|
||||||
10,4,27,11664,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,28,11665,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,29,11666,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,30,11667,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,31,11668,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,32,11669,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,33,11670,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,34,11671,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,35,11672,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,36,11673,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,37,11674,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,38,11675,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,39,11676,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,40,11677,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,41,11678,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,42,11679,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,43,11680,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,44,11681,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,45,11682,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,46,11683,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,47,11684,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,48,11685,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,49,11686,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,50,11687,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,51,11688,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,52,11689,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,53,11690,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,54,11691,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,55,11692,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,56,11693,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,57,11694,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,58,11695,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,59,11696,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,60,11697,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,61,12893,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,62,12894,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,63,12895,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,64,12896,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,65,12897,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,66,12898,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,67,12899,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,68,14337,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,69,14338,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,70,14339,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,71,14340,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,72,14341,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,73,14342,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,74,14343,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,75,14344,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,76,14345,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,77,9254,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,78,9255,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,79,9256,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,80,9257,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,81,9258,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,82,9259,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,83,9260,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,84,9261,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,85,9262,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,86,9263,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,87,9264,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,88,9265,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,89,9266,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,90,9267,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,91,9268,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,92,9269,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,93,9270,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,94,9271,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,95,9272,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,96,9273,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,97,9274,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,98,9275,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,99,9276,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,100,9277,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,101,9278,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,102,9279,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,103,9280,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,104,9281,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,105,9282,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,106,9283,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,107,9284,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,108,9285,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,109,9286,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,110,9287,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,111,9288,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,112,9289,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,113,9290,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,114,9291,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,115,9292,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,116,9293,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,117,9294,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,118,9295,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,119,9296,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,120,9297,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,121,9298,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,122,9299,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,123,9300,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,124,9301,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,125,13196,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,126,13197,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,127,13198,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,128,13199,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,129,15542,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,130,15543,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,131,15544,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,132,15545,10000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,133,13640,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,134,13641,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,135,13642,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,136,13643,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,137,13644,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,138,13645,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,139,13646,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,140,13647,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,141,13648,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,142,13649,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,143,13650,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,144,13651,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,145,13652,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,146,13653,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,147,13654,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,148,13655,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,149,13656,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,150,13657,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,151,13658,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,152,13659,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,153,13660,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,154,13661,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,155,13662,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,156,13663,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,157,13664,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,158,13665,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,159,13666,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,160,13667,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,161,13668,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,162,13669,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,163,13670,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,164,13671,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,165,13672,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,166,13673,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,167,13674,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,168,13675,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,169,13676,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,170,13677,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,171,13678,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,172,13679,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,173,13680,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,174,13681,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,175,13682,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,176,13683,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,177,13684,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,178,13685,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,179,13686,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,180,13687,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,181,13688,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,182,13689,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,183,13690,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,184,13691,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,185,15546,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,186,15547,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,187,15548,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,188,15549,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,189,16162,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,190,16163,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,191,16164,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,192,16165,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,193,16166,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,194,16167,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,195,16168,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,196,16169,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,197,16172,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,198,16173,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,199,16174,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,200,16175,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,201,16176,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,202,16177,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,203,16178,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,204,16179,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,205,16182,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,206,16183,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,207,16184,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,208,16185,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,209,16186,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,210,16187,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,211,16188,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,212,16189,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,213,16192,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,214,16193,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,215,16194,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,216,16195,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,217,16196,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,218,16197,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,219,16198,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,220,16199,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,221,16202,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,222,16203,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,223,16204,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,224,16205,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,225,16206,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,226,16207,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,227,16208,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,228,16209,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,229,16212,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,230,16213,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,231,16214,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,232,16215,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,233,16216,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,234,16217,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,235,16218,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,236,16219,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,237,16222,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,238,16223,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,239,16224,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,240,16225,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,241,16226,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,242,16227,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,243,16228,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,244,16229,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,245,16232,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,246,16233,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,247,16234,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,248,16235,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,249,16236,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,250,16237,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,251,16238,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,252,16239,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,253,16242,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,254,16243,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,255,16244,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,256,16245,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,257,16246,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,258,16247,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,259,16248,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,260,16249,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,261,16252,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,262,16253,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,263,16254,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,264,16255,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,265,16256,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,266,16257,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,267,16258,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,268,16259,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,269,16262,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,270,16263,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,271,16264,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,272,16265,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,273,16266,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,274,16267,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,275,16268,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,276,16269,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,277,16272,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,278,16273,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,279,16274,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,280,16275,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,281,16276,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,282,16277,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,283,16278,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,284,16279,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,285,16282,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,286,16283,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,287,16284,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,288,16285,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,289,16286,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,290,16287,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,291,16288,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,292,16289,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,293,16292,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,294,16293,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,295,16294,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,296,16295,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,297,16296,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,298,16297,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,299,16298,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,4,300,16299,35000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,301,14136,15000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,302,14137,15000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,303,14138,15000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,304,14139,15000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,305,14140,15000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,306,14141,15000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,307,14142,15000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,308,14143,15000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,309,14144,15000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,310,14145,15000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,311,14454,30000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,312,14455,30000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,313,14456,30000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,314,14457,30000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,315,14458,30000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,316,14459,30000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,317,14460,30000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,318,14461,30000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,319,14462,30000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,320,14463,30000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,321,12724,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,322,12725,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,323,12726,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,324,12727,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,325,12728,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,326,12729,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,327,12730,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,328,12731,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,329,12732,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,330,12733,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,331,12734,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,332,12735,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,333,12736,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,334,12737,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,335,12738,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,336,12739,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,337,12740,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,338,12741,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,339,12742,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,340,12743,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,341,12744,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,342,12745,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,343,12746,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,344,12747,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,345,12748,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,346,12749,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,347,12750,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,348,12751,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,349,12752,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,350,12753,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,351,15070,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,352,15071,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,353,15072,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,354,15073,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,355,15074,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,356,15075,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,357,15076,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,358,15077,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,359,15078,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,360,15079,50000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,361,15567,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,362,15568,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,363,15569,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,364,15570,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,365,15571,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,366,15572,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,367,15573,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,368,15574,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,369,15575,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,370,15576,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,371,15577,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,372,15578,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,373,15579,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,374,15580,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,375,15581,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,376,15582,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,377,15583,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,378,15584,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,379,15585,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,380,15586,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,381,15587,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,382,15588,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,383,15589,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,384,15590,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,385,15591,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,386,15592,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,387,15593,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,388,15594,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,389,15595,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,390,15596,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,391,15597,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,392,15598,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,393,15599,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,394,15600,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,395,15601,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,396,15602,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,397,15603,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,398,15604,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,399,15605,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,400,15606,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,401,15607,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,402,15608,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,403,15609,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,404,15610,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,405,15611,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,406,15612,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,407,15613,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,408,15614,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,409,15615,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,410,15616,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,411,15617,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,412,15618,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,413,15619,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,414,15620,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,415,15621,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,416,15622,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,417,15623,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,418,15624,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,419,15625,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,420,15626,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,421,15627,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,422,15628,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,423,15629,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,424,15630,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,425,15631,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,426,15632,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,427,15633,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,428,15634,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,429,15635,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,430,15636,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,431,15637,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,432,15638,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,433,15639,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,434,15640,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,435,15641,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,436,15642,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,437,15643,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,438,15644,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,439,15645,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,440,15646,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,441,15647,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,442,15648,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,443,15649,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,444,15650,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,445,15651,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,446,15652,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,447,15653,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,448,15654,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,449,15655,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,450,15656,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,451,15657,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,452,15658,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,453,15659,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,454,15660,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,455,15661,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,456,15662,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,457,15663,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,458,15664,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,459,15665,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,460,15666,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,461,15667,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,462,15668,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,463,15669,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,464,15670,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,465,15671,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,466,15672,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,467,15673,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,468,15674,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,469,15675,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,470,15676,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,471,15677,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,472,15678,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,473,15679,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,474,15680,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,475,15681,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,476,15682,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,477,15683,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,478,15684,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,479,15685,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,480,15686,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,481,15687,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,482,15688,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,483,15689,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,484,15690,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,485,15691,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,486,15692,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,487,15693,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,488,15694,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,489,15695,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,490,15696,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,491,15697,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,492,15698,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,493,15699,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,494,15700,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,495,15701,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,496,15702,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,497,15703,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,498,15704,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,499,15705,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,500,15706,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,501,15707,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,502,15708,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,503,15709,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,504,15710,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,505,15711,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,506,15712,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,507,15713,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,508,15714,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,509,15715,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,510,15716,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,511,15717,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,512,15718,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,513,15719,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,514,15720,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,515,15721,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,516,15722,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,517,15723,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,518,15724,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,519,15725,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,520,15726,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,521,15727,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,522,15728,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,523,15729,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,524,15730,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,525,15731,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,526,15732,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,527,15733,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,528,15734,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,529,15735,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,530,15736,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,531,15737,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,532,15738,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,533,15739,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,534,15740,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,535,15741,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,536,15742,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,537,15743,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,538,15744,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,539,15745,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,540,15746,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,541,15747,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,542,15748,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,543,15749,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,544,15750,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,545,15751,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,546,15752,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,547,15753,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,548,15754,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,549,15755,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,550,15756,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,551,15757,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,552,15758,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,553,15759,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,554,15760,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,555,15761,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,556,15762,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,557,15763,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,558,15764,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,559,15765,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,560,15766,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,561,15919,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,562,15920,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,563,15921,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,564,15922,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,565,15923,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,566,15924,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,567,15925,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,568,15926,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,569,15927,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,570,15928,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,571,15929,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,572,15930,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,573,15931,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,574,15932,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,575,15933,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,576,15934,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,577,15935,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,578,15936,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,579,15937,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,580,15938,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,581,15939,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,582,15940,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,583,15941,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,584,15942,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,585,15943,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,586,15944,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,587,15945,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,588,15946,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,589,15947,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,590,15948,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,591,15949,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,592,15950,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,593,15951,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,594,15952,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,595,15953,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,596,15954,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,597,15955,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,598,15956,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,599,15957,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,600,15958,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,601,15959,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,602,15960,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,603,15961,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,604,15962,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,605,15963,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,606,15964,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,607,15965,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,608,15966,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,609,15967,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,610,15968,20000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,7,611,13506,250,1,0,0,1,1,0,1,50,0
|
|
||||||
10,7,612,15011,250,1,0,0,1,1,0,1,50,0
|
|
||||||
10,7,613,13636,250,1,0,0,1,1,0,1,50,0
|
|
||||||
10,7,614,1227,250,1,0,0,1,1,0,1,50,0
|
|
||||||
10,7,615,15022,250,1,0,0,1,1,0,1,50,0
|
|
||||||
10,8,616,4407,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,617,4408,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,618,4409,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,619,4410,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,620,4411,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,621,4412,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,622,4413,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,623,4414,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,624,4823,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,625,4824,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,626,4825,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,627,4826,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,628,4827,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,629,4828,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,630,4829,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,631,4830,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,632,5194,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,633,5195,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,634,5196,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,635,5197,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,636,5198,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,637,5199,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,638,5200,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,639,5201,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,640,13630,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,641,13631,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,642,13632,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,643,13633,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,644,13634,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,645,13635,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,646,15103,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,647,15104,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,648,15105,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,649,15106,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,650,15107,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,651,15108,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,652,16459,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,653,16460,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,654,16461,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,655,16462,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,656,16463,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,657,16464,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,658,16465,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,659,16466,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,660,16467,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,661,16468,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,662,16469,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,663,16470,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,664,16471,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,665,16472,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,666,13416,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,667,13417,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,668,13418,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,669,13419,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,670,13420,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,671,14283,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,672,14284,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,673,14285,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,674,14286,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,675,13182,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,676,13507,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,677,13981,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,678,14744,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,679,14893,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,680,15785,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,681,16419,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,682,11470,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,683,12512,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,684,12884,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,685,12513,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,686,12514,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,687,12515,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,688,12516,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,689,12517,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,690,12518,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,691,12519,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,692,12520,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,693,12521,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,694,8179,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,695,9704,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,696,15448,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,697,11162,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,698,11163,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,699,11164,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,700,11165,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,701,11661,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,702,11662,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,703,14639,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,704,13607,10,1,0,0,1,1,0,1,0,0
|
|
||||||
10,7,705,15774,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,706,15775,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,707,11420,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,708,14704,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,709,13177,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,710,14191,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,711,13449,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,712,14192,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,713,15772,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,714,13791,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,715,14006,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,716,15768,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,717,14069,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,718,14124,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,719,15507,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,720,15508,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,721,14855,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,722,14894,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,723,16444,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,724,16445,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,725,12509,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,726,14126,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,727,15062,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,728,15063,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,729,14891,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,730,14895,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,731,14091,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,732,14092,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,733,14501,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,734,14506,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,735,15285,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,736,15286,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,737,16442,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,738,16443,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,739,15027,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,740,15028,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,741,13453,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,742,14193,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,743,13178,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,744,14194,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,745,16454,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,746,16455,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,747,15030,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,748,15031,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,749,13790,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,750,14005,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,751,14406,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,752,14413,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,753,16448,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,754,16449,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,755,12872,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,756,14187,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,757,14125,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,758,14500,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,759,14505,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,760,15118,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,761,15119,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,762,14662,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,763,14663,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,764,15771,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,765,9700,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,766,14498,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,767,14913,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,768,14914,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,769,13508,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,770,15115,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,771,15116,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,772,15113,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,773,15114,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,774,15222,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,775,15223,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,776,10750,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,777,14705,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,778,15027,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,779,15028,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,780,10380,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,781,15060,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,782,13963,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,783,14026,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,784,13964,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,785,14027,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,786,15064,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,787,15065,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,788,15524,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,789,15525,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,790,16450,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,791,16451,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,792,16344,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,793,16345,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,794,16342,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,795,16343,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,796,15220,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,797,15221,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,798,15066,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,799,15067,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,800,14089,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,801,14090,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,802,14195,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,803,14196,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,804,13965,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,805,14028,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,806,13508,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,807,13962,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,808,14314,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,809,13404,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,810,14188,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,811,14032,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,812,13960,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,813,15819,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,814,15820,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,815,10750,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,816,14705,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,817,14407,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,818,14414,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,819,16352,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,820,16353,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,821,14502,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,822,14507,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,823,10811,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,824,15061,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,825,15823,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,826,15824,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,827,15224,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,828,15225,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,829,14503,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,830,14510,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,831,15776,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,832,15777,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,833,15821,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,834,15822,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,835,14198,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,836,14197,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,837,16446,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,838,16447,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,839,14905,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,840,14907,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,841,14904,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,842,14906,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,843,14659,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,844,14660,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,845,13326,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,846,14416,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,847,13450,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,848,14031,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,849,16492,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,7,850,16493,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,8,851,1520,1,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,852,7011,1,1,0,0,1,1,0,1,0,0
|
|
||||||
10,7,853,14299,500,1,0,0,1,1,0,1,20,0
|
|
||||||
10,7,854,14389,500,1,0,0,1,1,0,1,20,0
|
|
||||||
10,7,855,15177,500,1,0,0,1,1,0,1,20,0
|
|
||||||
10,7,856,14537,500,1,0,0,1,1,0,1,20,0
|
|
||||||
10,7,857,14758,500,1,0,0,1,1,0,1,20,0
|
|
||||||
10,7,858,14854,500,1,0,0,1,1,0,1,20,0
|
|
||||||
10,7,859,13974,500,1,0,0,1,1,0,1,20,0
|
|
||||||
10,7,860,15021,500,1,0,0,1,1,0,1,20,0
|
|
||||||
10,7,861,15111,500,1,0,0,1,1,0,1,20,0
|
|
||||||
10,7,862,15226,500,1,0,0,1,1,0,1,20,0
|
|
||||||
10,7,863,15773,500,1,0,0,1,1,0,1,20,0
|
|
||||||
10,7,864,15825,500,1,0,0,1,1,0,1,20,0
|
|
||||||
10,7,865,15827,500,1,0,0,1,1,0,1,20,0
|
|
||||||
10,7,866,16340,500,1,0,0,1,1,0,1,20,0
|
|
||||||
10,7,867,16341,500,1,0,0,1,1,0,1,20,0
|
|
||||||
10,7,868,16457,500,1,0,0,1,1,0,1,20,0
|
|
||||||
10,7,869,16458,500,1,0,0,1,1,0,1,20,0
|
|
||||||
10,7,870,11698,250,1,0,0,1,1,0,1,50,0
|
|
||||||
10,7,871,11700,250,1,0,0,1,1,0,1,50,0
|
|
||||||
10,8,872,4358,10,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,873,7981,1,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,874,7267,20,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,875,9958,20,1,0,0,1,1,0,1,0,999
|
|
||||||
10,8,876,1548,20,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,877,1613,20,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,878,1026,1,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,879,5380,1,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,880,11284,15,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,881,11285,15,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,882,11286,15,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,883,10356,500,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,884,12511,500,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,885,13238,500,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,886,1691,1,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,887,9708,1,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,888,11383,10,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,889,11382,10,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,890,11381,10,1,0,0,1,1,0,1,0,0
|
|
||||||
10,7,891,16348,3000,1,0,0,1,1,0,1,100,0
|
|
||||||
10,8,892,11386,10,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,893,5767,1,10000,0,0,1,1,0,1,0,0
|
|
||||||
10,8,894,5765,1,10000,0,0,1,1,0,1,0,0
|
|
||||||
10,8,895,5768,1,10000,0,0,1,1,0,1,0,0
|
|
||||||
10,8,896,14444,10,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,897,14443,10,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,898,14445,10,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,899,15068,500,1,0,0,1,1,0,1,20,0
|
|
||||||
10,7,900,16532,1000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,901,100,1,10000,0,0,1,1,0,1,0,0
|
|
||||||
10,8,902,11243,1,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,903,101,1,10000,0,0,1,1,0,1,0,0
|
|
||||||
10,7,904,14368,3000,1,0,0,1,1,0,1,50,0
|
|
||||||
10,8,905,8943,1,20,0,0,1,1,0,1,0,0
|
|
||||||
10,7,906,1622,3000,1,0,0,1,1,0,1,0,0
|
|
||||||
10,8,907,8953,1,20,0,0,1,1,0,1,0,0
|
|
||||||
10,8,908,13693,1,20,0,0,1,1,0,1,0,0
|
|
||||||
10,8,909,8949,1,20,0,0,1,1,0,1,0,0
|
|
||||||
10,8,910,8955,1,20,0,0,1,1,0,1,0,0
|
|
||||||
10,7,911,16456,500,1,0,0,1,1,0,1,0,0
|
|
||||||
|
0
bin/questlists/.gitkeep
Normal file
0
bin/questlists/.gitkeep
Normal file
260
bundled-schema/FestaDefaults.sql
Normal file
260
bundled-schema/FestaDefaults.sql
Normal file
@@ -0,0 +1,260 @@
|
|||||||
|
BEGIN;
|
||||||
|
|
||||||
|
-- Ripped prizes
|
||||||
|
INSERT INTO public.festa_prizes
|
||||||
|
(type, tier, souls_req, item_id, num_item)
|
||||||
|
VALUES
|
||||||
|
('personal', 1, 1, 9647, 7),
|
||||||
|
('personal', 2, 1, 9647, 7),
|
||||||
|
('personal', 3, 1, 9647, 7),
|
||||||
|
('personal', 1, 200, 11284, 4),
|
||||||
|
('personal', 2, 200, 11284, 4),
|
||||||
|
('personal', 3, 200, 11284, 4),
|
||||||
|
('personal', 1, 400, 11381, 3),
|
||||||
|
('personal', 2, 400, 11381, 3),
|
||||||
|
('personal', 3, 400, 11381, 3),
|
||||||
|
('personal', 1, 600, 11284, 8),
|
||||||
|
('personal', 2, 600, 11284, 8),
|
||||||
|
('personal', 3, 600, 11284, 8),
|
||||||
|
('personal', 1, 800, 11384, 3),
|
||||||
|
('personal', 2, 800, 11384, 3),
|
||||||
|
('personal', 3, 800, 11384, 3),
|
||||||
|
('personal', 1, 1000, 11284, 12),
|
||||||
|
('personal', 2, 1000, 11284, 12),
|
||||||
|
('personal', 3, 1000, 11284, 12),
|
||||||
|
('personal', 1, 1200, 11381, 5),
|
||||||
|
('personal', 2, 1200, 11381, 5),
|
||||||
|
('personal', 3, 1200, 11381, 5),
|
||||||
|
('personal', 1, 1400, 11284, 16),
|
||||||
|
('personal', 2, 1400, 11284, 16),
|
||||||
|
('personal', 3, 1400, 11284, 16),
|
||||||
|
('personal', 1, 1700, 11384, 5),
|
||||||
|
('personal', 2, 1700, 11384, 5),
|
||||||
|
('personal', 3, 1700, 11384, 5),
|
||||||
|
('personal', 1, 2000, 11284, 16),
|
||||||
|
('personal', 2, 2000, 11284, 16),
|
||||||
|
('personal', 3, 2000, 11284, 16),
|
||||||
|
('personal', 1, 2500, 11382, 4),
|
||||||
|
('personal', 2, 2500, 11382, 4),
|
||||||
|
('personal', 3, 2500, 11382, 4),
|
||||||
|
('personal', 1, 3000, 11284, 24),
|
||||||
|
('personal', 2, 3000, 11284, 24),
|
||||||
|
('personal', 3, 3000, 11284, 24),
|
||||||
|
('personal', 1, 4000, 11385, 4),
|
||||||
|
('personal', 2, 4000, 11385, 4),
|
||||||
|
('personal', 3, 4000, 11385, 4),
|
||||||
|
('personal', 1, 5000, 11381, 11),
|
||||||
|
('personal', 2, 5000, 11381, 11),
|
||||||
|
('personal', 3, 5000, 11381, 11),
|
||||||
|
('personal', 1, 6000, 5177, 5),
|
||||||
|
('personal', 2, 6000, 5177, 5),
|
||||||
|
('personal', 3, 6000, 5177, 5),
|
||||||
|
('personal', 1, 7000, 11384, 11),
|
||||||
|
('personal', 2, 7000, 11384, 11),
|
||||||
|
('personal', 3, 7000, 11384, 11),
|
||||||
|
('personal', 1, 10000, 11382, 8),
|
||||||
|
('personal', 2, 10000, 11382, 8),
|
||||||
|
('personal', 3, 10000, 11382, 8),
|
||||||
|
('personal', 1, 15000, 11385, 4),
|
||||||
|
('personal', 2, 15000, 11385, 4),
|
||||||
|
('personal', 3, 15000, 11385, 4),
|
||||||
|
('personal', 1, 20000, 11381, 13),
|
||||||
|
('personal', 2, 20000, 11381, 13),
|
||||||
|
('personal', 3, 20000, 11381, 13),
|
||||||
|
('personal', 1, 25000, 11385, 4),
|
||||||
|
('personal', 2, 25000, 11385, 4),
|
||||||
|
('personal', 3, 25000, 11385, 4),
|
||||||
|
('personal', 1, 30000, 11383, 1),
|
||||||
|
('personal', 2, 30000, 11383, 1),
|
||||||
|
('personal', 3, 30000, 11383, 1);
|
||||||
|
|
||||||
|
INSERT INTO public.festa_prizes
|
||||||
|
(type, tier, souls_req, item_id, num_item)
|
||||||
|
VALUES
|
||||||
|
('guild', 1, 100, 7468, 5),
|
||||||
|
('guild', 2, 100, 7468, 5),
|
||||||
|
('guild', 3, 100, 7465, 5),
|
||||||
|
('guild', 1, 300, 7469, 5),
|
||||||
|
('guild', 2, 300, 7469, 5),
|
||||||
|
('guild', 3, 300, 7466, 5),
|
||||||
|
('guild', 1, 700, 7470, 5),
|
||||||
|
('guild', 2, 700, 7470, 5),
|
||||||
|
('guild', 3, 700, 7467, 5),
|
||||||
|
('guild', 1, 1500, 13405, 14),
|
||||||
|
('guild', 1, 1500, 1520, 3),
|
||||||
|
('guild', 2, 1500, 13405, 14),
|
||||||
|
('guild', 2, 1500, 1520, 3),
|
||||||
|
('guild', 3, 1500, 7011, 3),
|
||||||
|
('guild', 3, 1500, 13405, 14),
|
||||||
|
('guild', 1, 3000, 10201, 10),
|
||||||
|
('guild', 2, 3000, 10201, 10),
|
||||||
|
('guild', 3, 3000, 10201, 10),
|
||||||
|
('guild', 1, 6000, 13895, 14),
|
||||||
|
('guild', 1, 6000, 1520, 6),
|
||||||
|
('guild', 2, 6000, 13895, 14),
|
||||||
|
('guild', 2, 6000, 1520, 6),
|
||||||
|
('guild', 3, 6000, 13895, 14),
|
||||||
|
('guild', 3, 6000, 7011, 4),
|
||||||
|
('guild', 1, 12000, 13406, 14),
|
||||||
|
('guild', 1, 12000, 1520, 9),
|
||||||
|
('guild', 2, 12000, 13406, 14),
|
||||||
|
('guild', 2, 12000, 1520, 9),
|
||||||
|
('guild', 3, 12000, 13406, 14),
|
||||||
|
('guild', 3, 12000, 7011, 5),
|
||||||
|
('guild', 1, 25000, 10207, 10),
|
||||||
|
('guild', 2, 25000, 10207, 10),
|
||||||
|
('guild', 3, 25000, 10207, 10),
|
||||||
|
('guild', 1, 50000, 1520, 12),
|
||||||
|
('guild', 1, 50000, 13896, 14),
|
||||||
|
('guild', 2, 50000, 1520, 12),
|
||||||
|
('guild', 2, 50000, 13896, 14),
|
||||||
|
('guild', 3, 50000, 7011, 6),
|
||||||
|
('guild', 3, 50000, 13896, 14),
|
||||||
|
('guild', 1, 100000, 10201, 10),
|
||||||
|
('guild', 2, 100000, 10201, 10),
|
||||||
|
('guild', 3, 100000, 10201, 10),
|
||||||
|
('guild', 1, 200000, 13406, 16),
|
||||||
|
('guild', 2, 200000, 13406, 16),
|
||||||
|
('guild', 3, 200000, 13406, 16),
|
||||||
|
('guild', 1, 300000, 13896, 16),
|
||||||
|
('guild', 2, 300000, 13896, 16),
|
||||||
|
('guild', 3, 300000, 13896, 16),
|
||||||
|
('guild', 1, 400000, 10207, 10),
|
||||||
|
('guild', 2, 400000, 10207, 10),
|
||||||
|
('guild', 3, 400000, 10207, 10),
|
||||||
|
('guild', 1, 500000, 13407, 6),
|
||||||
|
('guild', 1, 500000, 13897, 6),
|
||||||
|
('guild', 2, 500000, 13407, 6),
|
||||||
|
('guild', 2, 500000, 13897, 6),
|
||||||
|
('guild', 3, 500000, 13407, 6),
|
||||||
|
('guild', 3, 500000, 13897, 6);
|
||||||
|
|
||||||
|
-- Ripped trials
|
||||||
|
INSERT INTO public.festa_trials
|
||||||
|
(objective, goal_id, times_req, locale_req, reward)
|
||||||
|
VALUES
|
||||||
|
(1,27,1,0,1),
|
||||||
|
(5,53034,0,0,400),
|
||||||
|
(5,22042,0,0,89),
|
||||||
|
(5,23397,0,0,89),
|
||||||
|
(1,28,1,0,1),
|
||||||
|
(1,68,1,0,1),
|
||||||
|
(1,6,1,0,2),
|
||||||
|
(1,38,1,0,2),
|
||||||
|
(1,20,1,0,3),
|
||||||
|
(1,39,1,0,4),
|
||||||
|
(1,48,1,0,4),
|
||||||
|
(1,67,1,0,4),
|
||||||
|
(1,93,1,0,4),
|
||||||
|
(1,22,1,0,5),
|
||||||
|
(1,52,1,0,5),
|
||||||
|
(1,101,1,0,5),
|
||||||
|
(1,1,1,0,5),
|
||||||
|
(1,37,1,0,5),
|
||||||
|
(1,15,1,0,5),
|
||||||
|
(1,45,1,0,5),
|
||||||
|
(1,74,1,0,5),
|
||||||
|
(1,78,1,0,5),
|
||||||
|
(1,103,1,0,5),
|
||||||
|
(1,51,1,0,6),
|
||||||
|
(1,17,1,0,6),
|
||||||
|
(1,21,1,0,6),
|
||||||
|
(1,92,1,0,6),
|
||||||
|
(1,47,1,0,7),
|
||||||
|
(1,46,1,0,7),
|
||||||
|
(1,26,1,0,7),
|
||||||
|
(1,14,1,0,7),
|
||||||
|
(1,11,1,0,7),
|
||||||
|
(1,44,1,0,8),
|
||||||
|
(1,43,1,0,8),
|
||||||
|
(1,49,1,0,8),
|
||||||
|
(1,40,1,0,8),
|
||||||
|
(1,76,1,0,8),
|
||||||
|
(1,89,1,0,8),
|
||||||
|
(1,94,1,0,8),
|
||||||
|
(1,96,1,0,8),
|
||||||
|
(1,75,1,0,8),
|
||||||
|
(1,91,1,0,8),
|
||||||
|
(1,53,1,0,9),
|
||||||
|
(1,80,1,0,9),
|
||||||
|
(1,42,1,0,9),
|
||||||
|
(1,79,1,0,9),
|
||||||
|
(1,81,1,0,10),
|
||||||
|
(1,41,1,0,10),
|
||||||
|
(1,82,1,0,10),
|
||||||
|
(1,90,1,0,10),
|
||||||
|
(1,149,1,0,10),
|
||||||
|
(1,85,1,0,11),
|
||||||
|
(1,95,1,0,11),
|
||||||
|
(1,121,1,0,11),
|
||||||
|
(1,142,1,0,11),
|
||||||
|
(1,141,1,0,11),
|
||||||
|
(1,146,1,0,12),
|
||||||
|
(1,147,1,0,12),
|
||||||
|
(1,148,1,0,12),
|
||||||
|
(1,151,1,0,12),
|
||||||
|
(1,152,1,0,12),
|
||||||
|
(1,159,1,0,12),
|
||||||
|
(1,153,1,0,12),
|
||||||
|
(1,162,1,0,12),
|
||||||
|
(1,111,1,0,13),
|
||||||
|
(1,110,1,0,13),
|
||||||
|
(1,112,1,0,13),
|
||||||
|
(1,109,1,0,14),
|
||||||
|
(1,169,1,0,15),
|
||||||
|
(2,33,1,0,6),
|
||||||
|
(2,104,1,0,8),
|
||||||
|
(2,119,1,0,8),
|
||||||
|
(2,120,1,0,8),
|
||||||
|
(2,54,1,0,8),
|
||||||
|
(2,59,1,0,8),
|
||||||
|
(2,64,1,0,8),
|
||||||
|
(2,65,1,0,8),
|
||||||
|
(2,99,1,0,9),
|
||||||
|
(2,83,1,0,9),
|
||||||
|
(2,84,1,0,10),
|
||||||
|
(2,77,1,0,10),
|
||||||
|
(2,106,1,0,10),
|
||||||
|
(2,55,1,0,10),
|
||||||
|
(2,58,1,0,10),
|
||||||
|
(2,7,1,0,10),
|
||||||
|
(2,50,1,0,11),
|
||||||
|
(2,131,1,0,11),
|
||||||
|
(2,129,1,0,11),
|
||||||
|
(2,140,1,0,11),
|
||||||
|
(2,122,1,0,11),
|
||||||
|
(2,126,1,0,11),
|
||||||
|
(2,127,1,0,11),
|
||||||
|
(2,128,1,0,11),
|
||||||
|
(2,130,1,0,11),
|
||||||
|
(2,139,1,0,11),
|
||||||
|
(2,144,1,0,11),
|
||||||
|
(2,150,1,0,11),
|
||||||
|
(2,158,1,0,11),
|
||||||
|
(2,164,1,0,15),
|
||||||
|
(2,165,1,0,15),
|
||||||
|
(2,2,1,7,15),
|
||||||
|
(2,36,1,0,15),
|
||||||
|
(2,71,1,0,15),
|
||||||
|
(2,108,1,0,15),
|
||||||
|
(2,116,1,0,15),
|
||||||
|
(2,107,1,0,15),
|
||||||
|
(2,154,1,0,17),
|
||||||
|
(2,166,1,0,17),
|
||||||
|
(2,170,1,0,18),
|
||||||
|
(3,31,1,0,1),
|
||||||
|
(3,8,1,0,3),
|
||||||
|
(3,123,1,0,8),
|
||||||
|
(3,105,1,0,9),
|
||||||
|
(3,125,1,0,11),
|
||||||
|
(3,115,1,0,12),
|
||||||
|
(3,114,1,0,12),
|
||||||
|
(3,161,1,0,12),
|
||||||
|
(4,670,1,0,1),
|
||||||
|
(4,671,1,0,1),
|
||||||
|
(4,672,1,0,1),
|
||||||
|
(4,675,1,0,1),
|
||||||
|
(4,673,1,0,1),
|
||||||
|
(4,674,1,0,1);
|
||||||
|
|
||||||
|
END;
|
||||||
13
bundled-schema/NetcafeDefaults.sql
Normal file
13
bundled-schema/NetcafeDefaults.sql
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
BEGIN;
|
||||||
|
|
||||||
|
INSERT INTO public.cafebonus (time_req, item_type, item_id, quantity)
|
||||||
|
VALUES
|
||||||
|
(1800, 17, 0, 250),
|
||||||
|
(3600, 17, 0, 500),
|
||||||
|
(7200, 17, 0, 1000),
|
||||||
|
(10800, 17, 0, 1500),
|
||||||
|
(18000, 17, 0, 1750),
|
||||||
|
(28800, 17, 0, 3000),
|
||||||
|
(43200, 17, 0, 4000);
|
||||||
|
|
||||||
|
END;
|
||||||
918
bundled-schema/RoadShopItems.sql
Normal file
918
bundled-schema/RoadShopItems.sql
Normal file
@@ -0,0 +1,918 @@
|
|||||||
|
BEGIN;
|
||||||
|
|
||||||
|
INSERT INTO public.normal_shop_items
|
||||||
|
(shoptype, shopid, itemhash, itemid, points, tradequantity, rankreqlow, rankreqhigh, rankreqg, storelevelreq, maximumquantity, boughtquantity, roadfloorsrequired, weeklyfataliskills)
|
||||||
|
VALUES
|
||||||
|
(10,6,1,2146,25,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,6,2,2147,25,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,6,3,2148,25,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,6,4,2149,25,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,6,5,2150,25,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,6,6,2151,25,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,6,7,2152,25,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,6,8,2153,25,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,6,9,2154,25,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,6,10,2155,25,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,6,11,4398,25,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,6,12,12460,25,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,6,13,12461,25,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,6,14,12462,25,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,6,15,12463,25,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,6,16,12464,25,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,6,17,12465,25,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,6,18,12466,25,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,6,19,12467,25,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,6,20,12468,25,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,6,21,12469,25,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,6,22,15109,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,6,23,15110,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,6,24,2158,200,100,0,0,1,1,0,1,0,0),
|
||||||
|
(10,6,25,12306,2,1,0,0,1,1,0,1,80,0),
|
||||||
|
(10,6,26,12306,20000,10000,0,0,1,1,0,1,80,0),
|
||||||
|
(10,4,27,11664,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,28,11665,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,29,11666,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,30,11667,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,31,11668,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,32,11669,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,33,11670,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,34,11671,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,35,11672,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,36,11673,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,37,11674,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,38,11675,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,39,11676,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,40,11677,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,41,11678,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,42,11679,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,43,11680,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,44,11681,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,45,11682,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,46,11683,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,47,11684,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,48,11685,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,49,11686,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,50,11687,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,51,11688,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,52,11689,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,53,11690,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,54,11691,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,55,11692,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,56,11693,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,57,11694,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,58,11695,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,59,11696,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,60,11697,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,61,12893,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,62,12894,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,63,12895,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,64,12896,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,65,12897,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,66,12898,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,67,12899,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,68,14337,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,69,14338,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,70,14339,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,71,14340,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,72,14341,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,73,14342,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,74,14343,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,75,14344,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,76,14345,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,77,9254,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,78,9255,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,79,9256,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,80,9257,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,81,9258,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,82,9259,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,83,9260,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,84,9261,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,85,9262,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,86,9263,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,87,9264,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,88,9265,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,89,9266,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,90,9267,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,91,9268,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,92,9269,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,93,9270,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,94,9271,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,95,9272,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,96,9273,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,97,9274,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,98,9275,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,99,9276,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,100,9277,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,101,9278,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,102,9279,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,103,9280,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,104,9281,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,105,9282,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,106,9283,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,107,9284,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,108,9285,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,109,9286,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,110,9287,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,111,9288,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,112,9289,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,113,9290,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,114,9291,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,115,9292,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,116,9293,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,117,9294,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,118,9295,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,119,9296,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,120,9297,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,121,9298,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,122,9299,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,123,9300,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,124,9301,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,125,13196,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,126,13197,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,127,13198,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,128,13199,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,129,15542,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,130,15543,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,131,15544,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,132,15545,10000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,133,13640,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,134,13641,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,135,13642,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,136,13643,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,137,13644,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,138,13645,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,139,13646,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,140,13647,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,141,13648,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,142,13649,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,143,13650,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,144,13651,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,145,13652,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,146,13653,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,147,13654,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,148,13655,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,149,13656,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,150,13657,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,151,13658,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,152,13659,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,153,13660,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,154,13661,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,155,13662,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,156,13663,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,157,13664,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,158,13665,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,159,13666,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,160,13667,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,161,13668,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,162,13669,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,163,13670,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,164,13671,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,165,13672,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,166,13673,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,167,13674,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,168,13675,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,169,13676,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,170,13677,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,171,13678,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,172,13679,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,173,13680,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,174,13681,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,175,13682,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,176,13683,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,177,13684,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,178,13685,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,179,13686,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,180,13687,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,181,13688,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,182,13689,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,183,13690,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,184,13691,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,185,15546,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,186,15547,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,187,15548,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,188,15549,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,189,16162,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,190,16163,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,191,16164,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,192,16165,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,193,16166,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,194,16167,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,195,16168,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,196,16169,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,197,16172,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,198,16173,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,199,16174,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,200,16175,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,201,16176,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,202,16177,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,203,16178,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,204,16179,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,205,16182,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,206,16183,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,207,16184,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,208,16185,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,209,16186,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,210,16187,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,211,16188,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,212,16189,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,213,16192,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,214,16193,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,215,16194,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,216,16195,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,217,16196,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,218,16197,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,219,16198,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,220,16199,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,221,16202,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,222,16203,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,223,16204,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,224,16205,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,225,16206,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,226,16207,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,227,16208,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,228,16209,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,229,16212,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,230,16213,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,231,16214,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,232,16215,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,233,16216,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,234,16217,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,235,16218,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,236,16219,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,237,16222,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,238,16223,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,239,16224,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,240,16225,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,241,16226,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,242,16227,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,243,16228,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,244,16229,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,245,16232,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,246,16233,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,247,16234,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,248,16235,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,249,16236,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,250,16237,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,251,16238,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,252,16239,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,253,16242,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,254,16243,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,255,16244,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,256,16245,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,257,16246,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,258,16247,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,259,16248,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,260,16249,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,261,16252,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,262,16253,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,263,16254,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,264,16255,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,265,16256,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,266,16257,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,267,16258,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,268,16259,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,269,16262,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,270,16263,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,271,16264,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,272,16265,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,273,16266,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,274,16267,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,275,16268,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,276,16269,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,277,16272,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,278,16273,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,279,16274,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,280,16275,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,281,16276,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,282,16277,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,283,16278,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,284,16279,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,285,16282,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,286,16283,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,287,16284,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,288,16285,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,289,16286,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,290,16287,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,291,16288,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,292,16289,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,293,16292,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,294,16293,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,295,16294,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,296,16295,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,297,16296,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,298,16297,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,299,16298,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,4,300,16299,35000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,301,14136,15000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,302,14137,15000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,303,14138,15000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,304,14139,15000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,305,14140,15000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,306,14141,15000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,307,14142,15000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,308,14143,15000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,309,14144,15000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,310,14145,15000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,311,14454,30000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,312,14455,30000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,313,14456,30000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,314,14457,30000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,315,14458,30000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,316,14459,30000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,317,14460,30000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,318,14461,30000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,319,14462,30000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,320,14463,30000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,321,12724,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,322,12725,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,323,12726,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,324,12727,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,325,12728,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,326,12729,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,327,12730,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,328,12731,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,329,12732,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,330,12733,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,331,12734,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,332,12735,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,333,12736,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,334,12737,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,335,12738,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,336,12739,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,337,12740,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,338,12741,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,339,12742,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,340,12743,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,341,12744,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,342,12745,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,343,12746,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,344,12747,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,345,12748,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,346,12749,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,347,12750,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,348,12751,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,349,12752,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,350,12753,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,351,15070,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,352,15071,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,353,15072,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,354,15073,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,355,15074,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,356,15075,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,357,15076,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,358,15077,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,359,15078,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,360,15079,50000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,361,15567,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,362,15568,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,363,15569,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,364,15570,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,365,15571,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,366,15572,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,367,15573,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,368,15574,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,369,15575,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,370,15576,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,371,15577,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,372,15578,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,373,15579,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,374,15580,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,375,15581,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,376,15582,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,377,15583,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,378,15584,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,379,15585,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,380,15586,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,381,15587,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,382,15588,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,383,15589,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,384,15590,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,385,15591,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,386,15592,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,387,15593,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,388,15594,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,389,15595,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,390,15596,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,391,15597,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,392,15598,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,393,15599,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,394,15600,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,395,15601,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,396,15602,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,397,15603,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,398,15604,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,399,15605,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,400,15606,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,401,15607,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,402,15608,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,403,15609,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,404,15610,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,405,15611,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,406,15612,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,407,15613,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,408,15614,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,409,15615,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,410,15616,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,411,15617,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,412,15618,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,413,15619,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,414,15620,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,415,15621,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,416,15622,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,417,15623,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,418,15624,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,419,15625,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,420,15626,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,421,15627,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,422,15628,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,423,15629,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,424,15630,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,425,15631,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,426,15632,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,427,15633,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,428,15634,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,429,15635,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,430,15636,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,431,15637,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,432,15638,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,433,15639,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,434,15640,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,435,15641,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,436,15642,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,437,15643,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,438,15644,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,439,15645,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,440,15646,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,441,15647,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,442,15648,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,443,15649,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,444,15650,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,445,15651,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,446,15652,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,447,15653,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,448,15654,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,449,15655,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,450,15656,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,451,15657,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,452,15658,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,453,15659,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,454,15660,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,455,15661,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,456,15662,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,457,15663,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,458,15664,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,459,15665,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,460,15666,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,461,15667,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,462,15668,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,463,15669,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,464,15670,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,465,15671,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,466,15672,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,467,15673,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,468,15674,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,469,15675,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,470,15676,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,471,15677,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,472,15678,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,473,15679,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,474,15680,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,475,15681,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,476,15682,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,477,15683,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,478,15684,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,479,15685,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,480,15686,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,481,15687,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,482,15688,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,483,15689,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,484,15690,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,485,15691,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,486,15692,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,487,15693,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,488,15694,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,489,15695,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,490,15696,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,491,15697,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,492,15698,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,493,15699,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,494,15700,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,495,15701,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,496,15702,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,497,15703,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,498,15704,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,499,15705,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,500,15706,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,501,15707,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,502,15708,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,503,15709,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,504,15710,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,505,15711,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,506,15712,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,507,15713,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,508,15714,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,509,15715,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,510,15716,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,511,15717,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,512,15718,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,513,15719,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,514,15720,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,515,15721,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,516,15722,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,517,15723,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,518,15724,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,519,15725,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,520,15726,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,521,15727,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,522,15728,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,523,15729,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,524,15730,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,525,15731,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,526,15732,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,527,15733,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,528,15734,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,529,15735,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,530,15736,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,531,15737,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,532,15738,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,533,15739,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,534,15740,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,535,15741,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,536,15742,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,537,15743,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,538,15744,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,539,15745,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,540,15746,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,541,15747,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,542,15748,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,543,15749,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,544,15750,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,545,15751,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,546,15752,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,547,15753,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,548,15754,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,549,15755,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,550,15756,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,551,15757,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,552,15758,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,553,15759,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,554,15760,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,555,15761,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,556,15762,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,557,15763,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,558,15764,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,559,15765,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,560,15766,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,561,15919,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,562,15920,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,563,15921,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,564,15922,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,565,15923,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,566,15924,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,567,15925,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,568,15926,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,569,15927,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,570,15928,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,571,15929,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,572,15930,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,573,15931,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,574,15932,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,575,15933,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,576,15934,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,577,15935,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,578,15936,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,579,15937,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,580,15938,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,581,15939,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,582,15940,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,583,15941,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,584,15942,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,585,15943,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,586,15944,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,587,15945,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,588,15946,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,589,15947,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,590,15948,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,591,15949,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,592,15950,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,593,15951,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,594,15952,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,595,15953,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,596,15954,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,597,15955,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,598,15956,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,599,15957,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,600,15958,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,601,15959,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,602,15960,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,603,15961,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,604,15962,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,605,15963,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,606,15964,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,607,15965,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,608,15966,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,609,15967,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,610,15968,20000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,7,611,13506,250,1,0,0,1,1,0,1,50,0),
|
||||||
|
(10,7,612,15011,250,1,0,0,1,1,0,1,50,0),
|
||||||
|
(10,7,613,13636,250,1,0,0,1,1,0,1,50,0),
|
||||||
|
(10,7,614,1227,250,1,0,0,1,1,0,1,50,0),
|
||||||
|
(10,7,615,15022,250,1,0,0,1,1,0,1,50,0),
|
||||||
|
(10,8,616,4407,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,617,4408,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,618,4409,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,619,4410,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,620,4411,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,621,4412,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,622,4413,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,623,4414,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,624,4823,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,625,4824,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,626,4825,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,627,4826,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,628,4827,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,629,4828,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,630,4829,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,631,4830,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,632,5194,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,633,5195,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,634,5196,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,635,5197,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,636,5198,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,637,5199,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,638,5200,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,639,5201,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,640,13630,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,641,13631,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,642,13632,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,643,13633,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,644,13634,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,645,13635,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,646,15103,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,647,15104,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,648,15105,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,649,15106,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,650,15107,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,651,15108,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,652,16459,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,653,16460,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,654,16461,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,655,16462,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,656,16463,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,657,16464,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,658,16465,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,659,16466,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,660,16467,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,661,16468,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,662,16469,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,663,16470,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,664,16471,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,665,16472,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,666,13416,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,667,13417,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,668,13418,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,669,13419,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,670,13420,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,671,14283,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,672,14284,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,673,14285,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,674,14286,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,675,13182,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,676,13507,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,677,13981,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,678,14744,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,679,14893,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,680,15785,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,681,16419,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,682,11470,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,683,12512,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,684,12884,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,685,12513,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,686,12514,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,687,12515,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,688,12516,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,689,12517,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,690,12518,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,691,12519,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,692,12520,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,693,12521,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,694,8179,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,695,9704,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,696,15448,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,697,11162,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,698,11163,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,699,11164,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,700,11165,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,701,11661,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,702,11662,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,703,14639,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,704,13607,10,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,7,705,15774,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,706,15775,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,707,11420,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,708,14704,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,709,13177,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,710,14191,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,711,13449,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,712,14192,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,713,15772,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,714,13791,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,715,14006,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,716,15768,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,717,14069,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,718,14124,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,719,15507,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,720,15508,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,721,14855,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,722,14894,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,723,16444,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,724,16445,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,725,12509,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,726,14126,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,727,15062,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,728,15063,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,729,14891,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,730,14895,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,731,14091,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,732,14092,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,733,14501,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,734,14506,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,735,15285,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,736,15286,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,737,16442,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,738,16443,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,739,15027,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,740,15028,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,741,13453,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,742,14193,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,743,13178,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,744,14194,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,745,16454,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,746,16455,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,747,15030,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,748,15031,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,749,13790,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,750,14005,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,751,14406,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,752,14413,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,753,16448,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,754,16449,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,755,12872,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,756,14187,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,757,14125,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,758,14500,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,759,14505,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,760,15118,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,761,15119,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,762,14662,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,763,14663,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,764,15771,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,765,9700,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,766,14498,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,767,14913,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,768,14914,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,769,13508,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,770,15115,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,771,15116,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,772,15113,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,773,15114,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,774,15222,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,775,15223,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,776,10750,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,777,14705,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,778,15027,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,779,15028,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,780,10380,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,781,15060,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,782,13963,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,783,14026,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,784,13964,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,785,14027,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,786,15064,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,787,15065,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,788,15524,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,789,15525,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,790,16450,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,791,16451,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,792,16344,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,793,16345,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,794,16342,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,795,16343,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,796,15220,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,797,15221,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,798,15066,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,799,15067,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,800,14089,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,801,14090,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,802,14195,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,803,14196,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,804,13965,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,805,14028,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,806,13508,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,807,13962,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,808,14314,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,809,13404,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,810,14188,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,811,14032,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,812,13960,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,813,15819,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,814,15820,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,815,10750,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,816,14705,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,817,14407,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,818,14414,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,819,16352,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,820,16353,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,821,14502,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,822,14507,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,823,10811,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,824,15061,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,825,15823,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,826,15824,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,827,15224,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,828,15225,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,829,14503,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,830,14510,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,831,15776,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,832,15777,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,833,15821,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,834,15822,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,835,14198,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,836,14197,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,837,16446,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,838,16447,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,839,14905,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,840,14907,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,841,14904,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,842,14906,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,843,14659,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,844,14660,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,845,13326,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,846,14416,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,847,13450,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,848,14031,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,849,16492,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,7,850,16493,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,8,851,1520,1,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,852,7011,1,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,7,853,14299,500,1,0,0,1,1,0,1,20,0),
|
||||||
|
(10,7,854,14389,500,1,0,0,1,1,0,1,20,0),
|
||||||
|
(10,7,855,15177,500,1,0,0,1,1,0,1,20,0),
|
||||||
|
(10,7,856,14537,500,1,0,0,1,1,0,1,20,0),
|
||||||
|
(10,7,857,14758,500,1,0,0,1,1,0,1,20,0),
|
||||||
|
(10,7,858,14854,500,1,0,0,1,1,0,1,20,0),
|
||||||
|
(10,7,859,13974,500,1,0,0,1,1,0,1,20,0),
|
||||||
|
(10,7,860,15021,500,1,0,0,1,1,0,1,20,0),
|
||||||
|
(10,7,861,15111,500,1,0,0,1,1,0,1,20,0),
|
||||||
|
(10,7,862,15226,500,1,0,0,1,1,0,1,20,0),
|
||||||
|
(10,7,863,15773,500,1,0,0,1,1,0,1,20,0),
|
||||||
|
(10,7,864,15825,500,1,0,0,1,1,0,1,20,0),
|
||||||
|
(10,7,865,15827,500,1,0,0,1,1,0,1,20,0),
|
||||||
|
(10,7,866,16340,500,1,0,0,1,1,0,1,20,0),
|
||||||
|
(10,7,867,16341,500,1,0,0,1,1,0,1,20,0),
|
||||||
|
(10,7,868,16457,500,1,0,0,1,1,0,1,20,0),
|
||||||
|
(10,7,869,16458,500,1,0,0,1,1,0,1,20,0),
|
||||||
|
(10,7,870,11698,250,1,0,0,1,1,0,1,50,0),
|
||||||
|
(10,7,871,11700,250,1,0,0,1,1,0,1,50,0),
|
||||||
|
(10,8,872,4358,10,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,873,7981,1,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,874,7267,20,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,875,9958,20,1,0,0,1,1,0,1,0,999),
|
||||||
|
(10,8,876,1548,20,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,877,1613,20,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,878,1026,1,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,879,5380,1,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,880,11284,15,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,881,11285,15,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,882,11286,15,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,883,10356,500,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,884,12511,500,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,885,13238,500,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,886,1691,1,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,887,9708,1,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,888,11383,10,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,889,11382,10,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,890,11381,10,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,7,891,16348,3000,1,0,0,1,1,0,1,100,0),
|
||||||
|
(10,8,892,11386,10,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,893,5767,1,10000,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,894,5765,1,10000,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,895,5768,1,10000,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,896,14444,10,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,897,14443,10,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,898,14445,10,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,899,15068,500,1,0,0,1,1,0,1,20,0),
|
||||||
|
(10,7,900,16532,1000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,901,100,1,10000,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,902,11243,1,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,903,101,1,10000,0,0,1,1,0,1,0,0),
|
||||||
|
(10,7,904,14368,3000,1,0,0,1,1,0,1,50,0),
|
||||||
|
(10,8,905,8943,1,20,0,0,1,1,0,1,0,0),
|
||||||
|
(10,7,906,1622,3000,1,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,907,8953,1,20,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,908,13693,1,20,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,909,8949,1,20,0,0,1,1,0,1,0,0),
|
||||||
|
(10,8,910,8955,1,20,0,0,1,1,0,1,0,0),
|
||||||
|
(10,7,911,16456,500,1,0,0,1,1,0,1,0,0);
|
||||||
|
|
||||||
|
END;
|
||||||
135
config.json
135
config.json
@@ -2,14 +2,17 @@
|
|||||||
"Host": "127.0.0.1",
|
"Host": "127.0.0.1",
|
||||||
"BinPath": "bin",
|
"BinPath": "bin",
|
||||||
"DisableSoftCrash": false,
|
"DisableSoftCrash": false,
|
||||||
"devmode": true,
|
"FeaturedWeapons": 1,
|
||||||
"devmodeoptions": {
|
"DevMode": true,
|
||||||
"serverName" : "",
|
"DevModeOptions": {
|
||||||
|
"PatchServerManifest": "",
|
||||||
|
"PatchServerFile": "",
|
||||||
|
"AutoCreateAccount": true,
|
||||||
"EnableLauncherServer": false,
|
"EnableLauncherServer": false,
|
||||||
"hideLoginNotice": false,
|
"HideLoginNotice": false,
|
||||||
"loginNotice": "<BODY><CENTER><SIZE_3><C_4>Welcome to Erupe SU9.1 Beta!<BR><BODY><LEFT><SIZE_2><C_5>Erupe is experimental software<C_7>, we are not liable for any<BR><BODY>issues caused by installing the software!<BR><BODY><BR><BODY><C_4>■Report bugs on Discord!<C_7><BR><BODY><BR><BODY><C_4>■Test everything!<C_7><BR><BODY><BR><BODY><C_4>■Don't talk to softlocking NPCs!<C_7><BR><BODY><BR><BODY><C_4>■Fork the code on GitHub!<C_7><BR><BODY><BR><BODY>Thank you to all of the contributors,<BR><BODY><BR><BODY>this wouldn't exist without you.",
|
"LoginNotice": "<BODY><CENTER><SIZE_3><C_4>Welcome to Erupe SU9.1 Beta!<BR><BODY><LEFT><SIZE_2><C_5>Erupe is experimental software<C_7>, we are not liable for any<BR><BODY>issues caused by installing the software!<BR><BODY><BR><BODY><C_4>■Report bugs on Discord!<C_7><BR><BODY><BR><BODY><C_4>■Test everything!<C_7><BR><BODY><BR><BODY><C_4>■Don't talk to softlocking NPCs!<C_7><BR><BODY><BR><BODY><C_4>■Fork the code on GitHub!<C_7><BR><BODY><BR><BODY>Thank you to all of the contributors,<BR><BODY><BR><BODY>this wouldn't exist without you.",
|
||||||
"cleandb": false,
|
"CleanDB": false,
|
||||||
"maxlauncherhr": false,
|
"MaxLauncherHR": false,
|
||||||
"LogInboundMessages": false,
|
"LogInboundMessages": false,
|
||||||
"LogOutboundMessages": false,
|
"LogOutboundMessages": false,
|
||||||
"MaxHexdumpLength": 256,
|
"MaxHexdumpLength": 256,
|
||||||
@@ -20,64 +23,108 @@
|
|||||||
"MezFesAlt": false,
|
"MezFesAlt": false,
|
||||||
"DisableMailItems": true,
|
"DisableMailItems": true,
|
||||||
"DisableTokenCheck": false,
|
"DisableTokenCheck": false,
|
||||||
|
"QuestDebugTools": false,
|
||||||
"SaveDumps": {
|
"SaveDumps": {
|
||||||
"Enabled": true,
|
"Enabled": true,
|
||||||
"OutputDir": "savedata"
|
"OutputDir": "savedata"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"discord": {
|
"Discord": {
|
||||||
"enabled": false,
|
"Enabled": false,
|
||||||
"bottoken": "",
|
"BotToken": "",
|
||||||
"realtimeChannelID": ""
|
"RealtimeChannelID": ""
|
||||||
},
|
},
|
||||||
"database": {
|
"Commands": [
|
||||||
"host": "localhost",
|
{
|
||||||
"port": 5432,
|
"Name": "Rights",
|
||||||
"user": "postgres",
|
"Enabled": false,
|
||||||
"password": "",
|
"Prefix": "!rights"
|
||||||
"database": "erupe"
|
}, {
|
||||||
|
"Name": "Raviente",
|
||||||
|
"Enabled": true,
|
||||||
|
"Prefix": "!ravi"
|
||||||
|
}, {
|
||||||
|
"Name": "Teleport",
|
||||||
|
"Enabled": false,
|
||||||
|
"Prefix": "!tele"
|
||||||
|
}, {
|
||||||
|
"Name": "Reload",
|
||||||
|
"Enabled": true,
|
||||||
|
"Prefix": "!reload"
|
||||||
|
}, {
|
||||||
|
"Name": "KeyQuest",
|
||||||
|
"Enabled": false,
|
||||||
|
"Prefix": "!kqf"
|
||||||
|
}, {
|
||||||
|
"Name": "Course",
|
||||||
|
"Enabled": true,
|
||||||
|
"Prefix": "!course"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"Courses": [
|
||||||
|
{"Name": "HunterLife", "Enabled": true},
|
||||||
|
{"Name": "ExtraA", "Enabled": true},
|
||||||
|
{"Name": "Premium", "Enabled": true},
|
||||||
|
{"Name": "Assist", "Enabled": false},
|
||||||
|
{"Name": "Netcafe", "Enabled": false},
|
||||||
|
{"Name": "Hiden", "Enabled": false},
|
||||||
|
{"Name": "HunterSupport", "Enabled": false},
|
||||||
|
{"Name": "NetcafeBoost", "Enabled": false}
|
||||||
|
],
|
||||||
|
"Database": {
|
||||||
|
"Host": "localhost",
|
||||||
|
"Port": 5432,
|
||||||
|
"User": "postgres",
|
||||||
|
"Password": "",
|
||||||
|
"Database": "erupe"
|
||||||
},
|
},
|
||||||
"launcher": {
|
"Launcher": {
|
||||||
"port": 80,
|
"Enabled": false,
|
||||||
|
"Port": 80,
|
||||||
"UseOriginalLauncherFiles": false
|
"UseOriginalLauncherFiles": false
|
||||||
},
|
},
|
||||||
"sign": {
|
"Sign": {
|
||||||
"port": 53312
|
"Enabled": true,
|
||||||
|
"Port": 53312
|
||||||
},
|
},
|
||||||
"entrance": {
|
"Channel": {
|
||||||
"port": 53310,
|
"Enabled": true
|
||||||
"entries": [
|
},
|
||||||
|
"Entrance": {
|
||||||
|
"Enabled": true,
|
||||||
|
"Port": 53310,
|
||||||
|
"Entries": [
|
||||||
{
|
{
|
||||||
"name": "Newbie", "description": "", "ip": "", "type": 3, "recommended": 2, "allowedclientflags": 0,
|
"Name": "Newbie", "Description": "", "IP": "", "Type": 3, "Recommended": 2, "AllowedClientFlags": 0,
|
||||||
"channels": [
|
"Channels": [
|
||||||
{ "port": 54001, "MaxPlayers": 100 },
|
{ "Port": 54001, "MaxPlayers": 100 },
|
||||||
{ "port": 54002, "MaxPlayers": 100 }
|
{ "Port": 54002, "MaxPlayers": 100 }
|
||||||
]
|
]
|
||||||
}, {
|
}, {
|
||||||
"name": "Normal", "description": "", "ip": "", "type": 1, "recommended": 0, "allowedclientflags": 0,
|
"Name": "Normal", "Description": "", "IP": "", "Type": 1, "Recommended": 0, "AllowedClientFlags": 0,
|
||||||
"channels": [
|
"Channels": [
|
||||||
{ "port": 54003, "MaxPlayers": 100 },
|
{ "Port": 54003, "MaxPlayers": 100 },
|
||||||
{ "port": 54004, "MaxPlayers": 100 }
|
{ "Port": 54004, "MaxPlayers": 100 }
|
||||||
]
|
]
|
||||||
}, {
|
}, {
|
||||||
"name": "Cities", "description": "", "ip": "", "type": 2, "recommended": 0, "allowedclientflags": 0,
|
"Name": "Cities", "Description": "", "IP": "", "Type": 2, "Recommended": 0, "AllowedClientFlags": 0,
|
||||||
"channels": [
|
"Channels": [
|
||||||
{ "port": 54005, "MaxPlayers": 100 }
|
{ "Port": 54005, "MaxPlayers": 100 }
|
||||||
]
|
]
|
||||||
}, {
|
}, {
|
||||||
"name": "Tavern", "description": "", "ip": "", "type": 4, "recommended": 0, "allowedclientflags": 0,
|
"Name": "Tavern", "Description": "", "IP": "", "Type": 4, "Recommended": 0, "AllowedClientFlags": 0,
|
||||||
"channels": [
|
"Channels": [
|
||||||
{ "port": 54006, "MaxPlayers": 100 }
|
{ "Port": 54006, "MaxPlayers": 100 }
|
||||||
]
|
]
|
||||||
}, {
|
}, {
|
||||||
"name": "Return", "description": "", "ip": "", "type": 5, "recommended": 0, "allowedclientflags": 0,
|
"Name": "Return", "Description": "", "IP": "", "Type": 5, "Recommended": 0, "AllowedClientFlags": 0,
|
||||||
"channels": [
|
"Channels": [
|
||||||
{ "port": 54007, "MaxPlayers": 100 }
|
{ "Port": 54007, "MaxPlayers": 100 }
|
||||||
]
|
]
|
||||||
}, {
|
}, {
|
||||||
"name": "MezFes", "description": "", "ip": "", "type": 6, "recommended": 6, "allowedclientflags": 0,
|
"Name": "MezFes", "Description": "", "IP": "", "Type": 6, "Recommended": 6, "AllowedClientFlags": 0,
|
||||||
"channels": [
|
"Channels": [
|
||||||
{ "port": 54008, "MaxPlayers": 100 }
|
{ "Port": 54008, "MaxPlayers": 100 }
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
@@ -12,25 +15,29 @@ type Config struct {
|
|||||||
Host string `mapstructure:"Host"`
|
Host string `mapstructure:"Host"`
|
||||||
BinPath string `mapstructure:"BinPath"`
|
BinPath string `mapstructure:"BinPath"`
|
||||||
DisableSoftCrash bool // Disables the 'Press Return to exit' dialog allowing scripts to reboot the server automatically
|
DisableSoftCrash bool // Disables the 'Press Return to exit' dialog allowing scripts to reboot the server automatically
|
||||||
|
FeaturedWeapons int // Number of Active Feature weapons to generate daily
|
||||||
DevMode bool
|
DevMode bool
|
||||||
|
|
||||||
DevModeOptions DevModeOptions
|
DevModeOptions DevModeOptions
|
||||||
Discord Discord
|
Discord Discord
|
||||||
|
Commands []Command
|
||||||
|
Courses []Course
|
||||||
Database Database
|
Database Database
|
||||||
Launcher Launcher
|
Launcher Launcher
|
||||||
Sign Sign
|
Sign Sign
|
||||||
|
Channel Channel
|
||||||
Entrance Entrance
|
Entrance Entrance
|
||||||
}
|
}
|
||||||
|
|
||||||
// DevModeOptions holds various debug/temporary options for use while developing Erupe.
|
// DevModeOptions holds various debug/temporary options for use while developing Erupe.
|
||||||
type DevModeOptions struct {
|
type DevModeOptions struct {
|
||||||
ServerName string // To get specific instance server about (Current Players/Event Week)
|
PatchServerManifest string // Manifest patch server override
|
||||||
EnableLauncherServer bool // Enables the launcher server to be served on port 80
|
PatchServerFile string // File patch server override
|
||||||
|
AutoCreateAccount bool // Automatically create accounts if they don't exist
|
||||||
HideLoginNotice bool // Hide the Erupe notice on login
|
HideLoginNotice bool // Hide the Erupe notice on login
|
||||||
LoginNotice string // MHFML string of the login notice displayed
|
LoginNotice string // MHFML string of the login notice displayed
|
||||||
CleanDB bool // Automatically wipes the DB on server reset.
|
CleanDB bool // Automatically wipes the DB on server reset.
|
||||||
MaxLauncherHR bool // Sets the HR returned in the launcher to HR9 so that you can join non-beginner worlds.
|
MaxLauncherHR bool // Sets the HR returned in the launcher to HR7 so that you can join non-beginner worlds.
|
||||||
FixedStageID bool // Causes all move_stage to use the ID sl1Ns200p0a0u0 to get you into all stages
|
|
||||||
LogInboundMessages bool // Log all messages sent to the server
|
LogInboundMessages bool // Log all messages sent to the server
|
||||||
LogOutboundMessages bool // Log all messages sent to the clients
|
LogOutboundMessages bool // Log all messages sent to the clients
|
||||||
MaxHexdumpLength int // Maximum number of bytes printed when logs are enabled
|
MaxHexdumpLength int // Maximum number of bytes printed when logs are enabled
|
||||||
@@ -41,6 +48,7 @@ type DevModeOptions struct {
|
|||||||
MezFesAlt bool // Swaps out Volpakkun for Tokotoko
|
MezFesAlt bool // Swaps out Volpakkun for Tokotoko
|
||||||
DisableTokenCheck bool // Disables checking login token exists in the DB (security risk!)
|
DisableTokenCheck bool // Disables checking login token exists in the DB (security risk!)
|
||||||
DisableMailItems bool // Hack to prevent english versions of MHF from crashing
|
DisableMailItems bool // Hack to prevent english versions of MHF from crashing
|
||||||
|
QuestDebugTools bool // Enable various quest debug logs
|
||||||
SaveDumps SaveDumpOptions
|
SaveDumps SaveDumpOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,10 +61,20 @@ type SaveDumpOptions struct {
|
|||||||
type Discord struct {
|
type Discord struct {
|
||||||
Enabled bool
|
Enabled bool
|
||||||
BotToken string
|
BotToken string
|
||||||
ServerID string
|
|
||||||
RealtimeChannelID string
|
RealtimeChannelID string
|
||||||
DevRoles []string
|
}
|
||||||
DevMode bool
|
|
||||||
|
// Command is a channelserver chat command
|
||||||
|
type Command struct {
|
||||||
|
Name string
|
||||||
|
Enabled bool
|
||||||
|
Prefix string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Course represents a course within MHF
|
||||||
|
type Course struct {
|
||||||
|
Name string
|
||||||
|
Enabled bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Database holds the postgres database config.
|
// Database holds the postgres database config.
|
||||||
@@ -70,17 +88,24 @@ type Database struct {
|
|||||||
|
|
||||||
// Launcher holds the launcher server config.
|
// Launcher holds the launcher server config.
|
||||||
type Launcher struct {
|
type Launcher struct {
|
||||||
|
Enabled bool
|
||||||
Port int
|
Port int
|
||||||
UseOriginalLauncherFiles bool
|
UseOriginalLauncherFiles bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sign holds the sign server config.
|
// Sign holds the sign server config.
|
||||||
type Sign struct {
|
type Sign struct {
|
||||||
|
Enabled bool
|
||||||
Port int
|
Port int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Channel struct {
|
||||||
|
Enabled bool
|
||||||
|
}
|
||||||
|
|
||||||
// Entrance holds the entrance server config.
|
// Entrance holds the entrance server config.
|
||||||
type Entrance struct {
|
type Entrance struct {
|
||||||
|
Enabled bool
|
||||||
Port uint16
|
Port uint16
|
||||||
Entries []EntranceServerInfo
|
Entries []EntranceServerInfo
|
||||||
}
|
}
|
||||||
@@ -107,6 +132,17 @@ type EntranceChannelInfo struct {
|
|||||||
CurrentPlayers uint16
|
CurrentPlayers uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ErupeConfig *Config
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
var err error
|
||||||
|
ErupeConfig, err = LoadConfig()
|
||||||
|
if err != nil {
|
||||||
|
preventClose(fmt.Sprintf("Failed to load config: %s", err.Error()))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// getOutboundIP4 gets the preferred outbound ip4 of this machine
|
// getOutboundIP4 gets the preferred outbound ip4 of this machine
|
||||||
// From https://stackoverflow.com/a/37382208
|
// From https://stackoverflow.com/a/37382208
|
||||||
func getOutboundIP4() net.IP {
|
func getOutboundIP4() net.IP {
|
||||||
@@ -148,3 +184,20 @@ func LoadConfig() (*Config, error) {
|
|||||||
|
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func preventClose(text string) {
|
||||||
|
if ErupeConfig.DisableSoftCrash {
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
fmt.Println("\nFailed to start Erupe:\n" + text)
|
||||||
|
go wait()
|
||||||
|
fmt.Println("\nPress Enter/Return to exit...")
|
||||||
|
fmt.Scanln()
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func wait() {
|
||||||
|
for {
|
||||||
|
time.Sleep(time.Millisecond * 100)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
33
go.mod
33
go.mod
@@ -1,23 +1,38 @@
|
|||||||
module erupe-ce
|
module erupe-ce
|
||||||
|
|
||||||
go 1.16
|
go 1.19
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/bwmarrin/discordgo v0.23.2
|
github.com/bwmarrin/discordgo v0.23.2
|
||||||
github.com/golang/mock v1.6.0 // indirect
|
|
||||||
github.com/gorilla/handlers v1.5.1
|
github.com/gorilla/handlers v1.5.1
|
||||||
github.com/gorilla/mux v1.8.0
|
github.com/gorilla/mux v1.8.0
|
||||||
github.com/gorilla/websocket v1.4.2 // indirect
|
|
||||||
github.com/jmoiron/sqlx v1.3.4
|
github.com/jmoiron/sqlx v1.3.4
|
||||||
github.com/lib/pq v1.10.4
|
github.com/lib/pq v1.10.4
|
||||||
github.com/mitchellh/mapstructure v1.4.3 // indirect
|
|
||||||
github.com/sachaos/lottery v0.0.0-20180520074626-61949d99bd96
|
github.com/sachaos/lottery v0.0.0-20180520074626-61949d99bd96
|
||||||
github.com/spf13/viper v1.8.1
|
github.com/spf13/viper v1.8.1
|
||||||
|
go.uber.org/zap v1.18.1
|
||||||
|
golang.org/x/crypto v0.1.0
|
||||||
|
golang.org/x/exp v0.0.0-20221028150844-83b7d23a625f
|
||||||
|
golang.org/x/text v0.4.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/felixge/httpsnoop v1.0.1 // indirect
|
||||||
|
github.com/fsnotify/fsnotify v1.4.9 // indirect
|
||||||
|
github.com/golang/mock v1.6.0 // indirect
|
||||||
|
github.com/gorilla/websocket v1.4.2 // indirect
|
||||||
|
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||||
|
github.com/magiconair/properties v1.8.5 // indirect
|
||||||
|
github.com/mitchellh/mapstructure v1.4.3 // indirect
|
||||||
|
github.com/pelletier/go-toml v1.9.3 // indirect
|
||||||
|
github.com/spf13/afero v1.6.0 // indirect
|
||||||
|
github.com/spf13/cast v1.3.1 // indirect
|
||||||
|
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||||
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
|
github.com/subosito/gotenv v1.2.0 // indirect
|
||||||
go.uber.org/atomic v1.9.0 // indirect
|
go.uber.org/atomic v1.9.0 // indirect
|
||||||
go.uber.org/multierr v1.7.0 // indirect
|
go.uber.org/multierr v1.7.0 // indirect
|
||||||
go.uber.org/zap v1.18.1
|
golang.org/x/sys v0.1.0 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20211202192323-5770296d904e
|
gopkg.in/ini.v1 v1.62.0 // indirect
|
||||||
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
golang.org/x/text v0.3.7
|
|
||||||
golang.org/x/tools v0.1.8 // indirect
|
|
||||||
)
|
)
|
||||||
|
|||||||
40
go.sum
40
go.sum
@@ -78,9 +78,8 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME
|
|||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||||
|
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
|
||||||
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
||||||
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
|
|
||||||
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
|
|
||||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
@@ -189,9 +188,8 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV
|
|||||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||||
|
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
|
||||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
@@ -202,9 +200,8 @@ github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaW
|
|||||||
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
|
||||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
|
||||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
|
|
||||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
|
||||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
@@ -222,9 +219,8 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
|
|||||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ=
|
github.com/pelletier/go-toml v1.9.3 h1:zeC5b1GviRUyKYd6OJPvBU/mcVDVoL1OhT17FCt5dSQ=
|
||||||
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
|
||||||
|
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
||||||
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
@@ -265,7 +261,6 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
|||||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
|
||||||
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
|
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
|
||||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
||||||
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
|
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
|
||||||
@@ -295,8 +290,8 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
|
|||||||
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20211202192323-5770296d904e h1:MUP6MR3rJ7Gk9LEia0LP2ytiH6MuCfs7qYz+47jGdD8=
|
golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
|
||||||
golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
@@ -307,6 +302,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
|
|||||||
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
|
||||||
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
|
||||||
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
|
||||||
|
golang.org/x/exp v0.0.0-20221028150844-83b7d23a625f h1:Al51T6tzvuh3oiwX11vex3QgJ2XTedFPGmbEVh8cdoc=
|
||||||
|
golang.org/x/exp v0.0.0-20221028150844-83b7d23a625f/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
|
||||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
@@ -333,7 +330,6 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|||||||
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
@@ -370,8 +366,6 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v
|
|||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
@@ -435,12 +429,9 @@ golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
|
||||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d h1:FjkYO/PPp4Wi0EAUOVLxePm7qVW4r4ctbWpURyuOD0E=
|
|
||||||
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
@@ -449,9 +440,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
|||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
|
||||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
@@ -508,8 +498,7 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
|
|||||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||||
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||||
golang.org/x/tools v0.1.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w=
|
golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=
|
||||||
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
@@ -617,9 +606,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
|
|||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
|
||||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
|
||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||||
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
|
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
|
||||||
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||||
|
|||||||
87
main.go
87
main.go
@@ -14,13 +14,12 @@ import (
|
|||||||
"erupe-ce/server/entranceserver"
|
"erupe-ce/server/entranceserver"
|
||||||
"erupe-ce/server/launcherserver"
|
"erupe-ce/server/launcherserver"
|
||||||
"erupe-ce/server/signserver"
|
"erupe-ce/server/signserver"
|
||||||
|
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
_ "github.com/lib/pq"
|
_ "github.com/lib/pq"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
var erupeConfig *config.Config
|
|
||||||
|
|
||||||
// Temporary DB auto clean on startup for quick development & testing.
|
// Temporary DB auto clean on startup for quick development & testing.
|
||||||
func cleanDB(db *sqlx.DB) {
|
func cleanDB(db *sqlx.DB) {
|
||||||
_ = db.MustExec("DELETE FROM guild_characters")
|
_ = db.MustExec("DELETE FROM guild_characters")
|
||||||
@@ -36,27 +35,21 @@ func main() {
|
|||||||
defer zapLogger.Sync()
|
defer zapLogger.Sync()
|
||||||
logger := zapLogger.Named("main")
|
logger := zapLogger.Named("main")
|
||||||
|
|
||||||
logger.Info("Starting Erupe")
|
logger.Info("Starting Erupe (9.1b)")
|
||||||
|
|
||||||
// Load the configuration.
|
if config.ErupeConfig.Database.Password == "" {
|
||||||
erupeConfig, err = config.LoadConfig()
|
|
||||||
if err != nil {
|
|
||||||
preventClose(fmt.Sprintf("Failed to load config: %s", err.Error()))
|
|
||||||
}
|
|
||||||
|
|
||||||
if erupeConfig.Database.Password == "" {
|
|
||||||
preventClose("Database password is blank")
|
preventClose("Database password is blank")
|
||||||
}
|
}
|
||||||
|
|
||||||
if net.ParseIP(erupeConfig.Host) == nil {
|
if net.ParseIP(config.ErupeConfig.Host) == nil {
|
||||||
ips, _ := net.LookupIP(erupeConfig.Host)
|
ips, _ := net.LookupIP(config.ErupeConfig.Host)
|
||||||
for _, ip := range ips {
|
for _, ip := range ips {
|
||||||
if ip != nil {
|
if ip != nil {
|
||||||
erupeConfig.Host = ip.String()
|
config.ErupeConfig.Host = ip.String()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if net.ParseIP(erupeConfig.Host) == nil {
|
if net.ParseIP(config.ErupeConfig.Host) == nil {
|
||||||
preventClose("Invalid host address")
|
preventClose("Invalid host address")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,10 +57,10 @@ func main() {
|
|||||||
// Discord bot
|
// Discord bot
|
||||||
var discordBot *discordbot.DiscordBot = nil
|
var discordBot *discordbot.DiscordBot = nil
|
||||||
|
|
||||||
if erupeConfig.Discord.Enabled {
|
if config.ErupeConfig.Discord.Enabled {
|
||||||
bot, err := discordbot.NewDiscordBot(discordbot.Options{
|
bot, err := discordbot.NewDiscordBot(discordbot.Options{
|
||||||
Logger: logger,
|
Logger: logger,
|
||||||
Config: erupeConfig,
|
Config: config.ErupeConfig,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -90,11 +83,11 @@ func main() {
|
|||||||
// Create the postgres DB pool.
|
// Create the postgres DB pool.
|
||||||
connectString := fmt.Sprintf(
|
connectString := fmt.Sprintf(
|
||||||
"host=%s port=%d user=%s password=%s dbname= %s sslmode=disable",
|
"host=%s port=%d user=%s password=%s dbname= %s sslmode=disable",
|
||||||
erupeConfig.Database.Host,
|
config.ErupeConfig.Database.Host,
|
||||||
erupeConfig.Database.Port,
|
config.ErupeConfig.Database.Port,
|
||||||
erupeConfig.Database.User,
|
config.ErupeConfig.Database.User,
|
||||||
erupeConfig.Database.Password,
|
config.ErupeConfig.Database.Password,
|
||||||
erupeConfig.Database.Database,
|
config.ErupeConfig.Database.Database,
|
||||||
)
|
)
|
||||||
|
|
||||||
db, err := sqlx.Open("postgres", connectString)
|
db, err := sqlx.Open("postgres", connectString)
|
||||||
@@ -112,11 +105,9 @@ func main() {
|
|||||||
// Clear stale data
|
// Clear stale data
|
||||||
_ = db.MustExec("DELETE FROM sign_sessions")
|
_ = db.MustExec("DELETE FROM sign_sessions")
|
||||||
_ = db.MustExec("DELETE FROM servers")
|
_ = db.MustExec("DELETE FROM servers")
|
||||||
_ = db.MustExec("DELETE FROM cafe_accepted")
|
|
||||||
_ = db.MustExec("UPDATE characters SET cafe_time=0")
|
|
||||||
|
|
||||||
// Clean the DB if the option is on.
|
// Clean the DB if the option is on.
|
||||||
if erupeConfig.DevMode && erupeConfig.DevModeOptions.CleanDB {
|
if config.ErupeConfig.DevMode && config.ErupeConfig.DevModeOptions.CleanDB {
|
||||||
logger.Info("Cleaning DB")
|
logger.Info("Cleaning DB")
|
||||||
cleanDB(db)
|
cleanDB(db)
|
||||||
logger.Info("Done cleaning DB")
|
logger.Info("Done cleaning DB")
|
||||||
@@ -126,13 +117,13 @@ func main() {
|
|||||||
|
|
||||||
// Launcher HTTP server.
|
// Launcher HTTP server.
|
||||||
var launcherServer *launcherserver.Server
|
var launcherServer *launcherserver.Server
|
||||||
if erupeConfig.DevMode && erupeConfig.DevModeOptions.EnableLauncherServer {
|
if config.ErupeConfig.Launcher.Enabled {
|
||||||
launcherServer = launcherserver.NewServer(
|
launcherServer = launcherserver.NewServer(
|
||||||
&launcherserver.Config{
|
&launcherserver.Config{
|
||||||
Logger: logger.Named("launcher"),
|
Logger: logger.Named("launcher"),
|
||||||
ErupeConfig: erupeConfig,
|
ErupeConfig: config.ErupeConfig,
|
||||||
DB: db,
|
DB: db,
|
||||||
UseOriginalLauncherFiles: erupeConfig.Launcher.UseOriginalLauncherFiles,
|
UseOriginalLauncherFiles: config.ErupeConfig.Launcher.UseOriginalLauncherFiles,
|
||||||
})
|
})
|
||||||
err = launcherServer.Start()
|
err = launcherServer.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -142,10 +133,13 @@ func main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Entrance server.
|
// Entrance server.
|
||||||
entranceServer := entranceserver.NewServer(
|
|
||||||
|
var entranceServer *entranceserver.Server
|
||||||
|
if config.ErupeConfig.Entrance.Enabled {
|
||||||
|
entranceServer = entranceserver.NewServer(
|
||||||
&entranceserver.Config{
|
&entranceserver.Config{
|
||||||
Logger: logger.Named("entrance"),
|
Logger: logger.Named("entrance"),
|
||||||
ErupeConfig: erupeConfig,
|
ErupeConfig: config.ErupeConfig,
|
||||||
DB: db,
|
DB: db,
|
||||||
})
|
})
|
||||||
err = entranceServer.Start()
|
err = entranceServer.Start()
|
||||||
@@ -153,12 +147,16 @@ func main() {
|
|||||||
preventClose(fmt.Sprintf("Failed to start entrance server: %s", err.Error()))
|
preventClose(fmt.Sprintf("Failed to start entrance server: %s", err.Error()))
|
||||||
}
|
}
|
||||||
logger.Info("Started entrance server")
|
logger.Info("Started entrance server")
|
||||||
|
}
|
||||||
|
|
||||||
// Sign server.
|
// Sign server.
|
||||||
signServer := signserver.NewServer(
|
|
||||||
|
var signServer *signserver.Server
|
||||||
|
if config.ErupeConfig.Sign.Enabled {
|
||||||
|
signServer = signserver.NewServer(
|
||||||
&signserver.Config{
|
&signserver.Config{
|
||||||
Logger: logger.Named("sign"),
|
Logger: logger.Named("sign"),
|
||||||
ErupeConfig: erupeConfig,
|
ErupeConfig: config.ErupeConfig,
|
||||||
DB: db,
|
DB: db,
|
||||||
})
|
})
|
||||||
err = signServer.Start()
|
err = signServer.Start()
|
||||||
@@ -166,24 +164,27 @@ func main() {
|
|||||||
preventClose(fmt.Sprintf("Failed to start sign server: %s", err.Error()))
|
preventClose(fmt.Sprintf("Failed to start sign server: %s", err.Error()))
|
||||||
}
|
}
|
||||||
logger.Info("Started sign server")
|
logger.Info("Started sign server")
|
||||||
|
}
|
||||||
|
|
||||||
var channels []*channelserver.Server
|
var channels []*channelserver.Server
|
||||||
|
|
||||||
|
if config.ErupeConfig.Channel.Enabled {
|
||||||
channelQuery := ""
|
channelQuery := ""
|
||||||
si := 0
|
si := 0
|
||||||
ci := 0
|
ci := 0
|
||||||
count := 1
|
count := 1
|
||||||
for _, ee := range erupeConfig.Entrance.Entries {
|
for _, ee := range config.ErupeConfig.Entrance.Entries {
|
||||||
for _, ce := range ee.Channels {
|
for i, ce := range ee.Channels {
|
||||||
sid := (4096 + si*256) + (16 + ci)
|
sid := (4096 + si*256) + (16 + ci)
|
||||||
c := *channelserver.NewServer(&channelserver.Config{
|
c := *channelserver.NewServer(&channelserver.Config{
|
||||||
ID: uint16(sid),
|
ID: uint16(sid),
|
||||||
Logger: logger.Named("channel-" + fmt.Sprint(count)),
|
Logger: logger.Named("channel-" + fmt.Sprint(count)),
|
||||||
ErupeConfig: erupeConfig,
|
ErupeConfig: config.ErupeConfig,
|
||||||
DB: db,
|
DB: db,
|
||||||
DiscordBot: discordBot,
|
DiscordBot: discordBot,
|
||||||
})
|
})
|
||||||
if ee.IP == "" {
|
if ee.IP == "" {
|
||||||
c.IP = erupeConfig.Host
|
c.IP = config.ErupeConfig.Host
|
||||||
} else {
|
} else {
|
||||||
c.IP = ee.IP
|
c.IP = ee.IP
|
||||||
}
|
}
|
||||||
@@ -192,7 +193,7 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
preventClose(fmt.Sprintf("Failed to start channel server: %s", err.Error()))
|
preventClose(fmt.Sprintf("Failed to start channel server: %s", err.Error()))
|
||||||
} else {
|
} else {
|
||||||
channelQuery += fmt.Sprintf("INSERT INTO servers (server_id, season, current_players) VALUES (%d, %d, 0);", sid, si%3)
|
channelQuery += fmt.Sprintf(`INSERT INTO servers (server_id, season, current_players, world_name, world_description, land) VALUES (%d, %d, 0, '%s', '%s', %d);`, sid, si%3, ee.Name, ee.Description, i+1)
|
||||||
channels = append(channels, &c)
|
channels = append(channels, &c)
|
||||||
logger.Info(fmt.Sprintf("Started channel server %d on port %d", count, ce.Port))
|
logger.Info(fmt.Sprintf("Started channel server %d on port %d", count, ce.Port))
|
||||||
ci++
|
ci++
|
||||||
@@ -209,6 +210,7 @@ func main() {
|
|||||||
for _, c := range channels {
|
for _, c := range channels {
|
||||||
c.Channels = channels
|
c.Channels = channels
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Wait for exit or interrupt with ctrl+C.
|
// Wait for exit or interrupt with ctrl+C.
|
||||||
c := make(chan os.Signal, 1)
|
c := make(chan os.Signal, 1)
|
||||||
@@ -217,12 +219,21 @@ func main() {
|
|||||||
|
|
||||||
logger.Info("Trying to shutdown gracefully")
|
logger.Info("Trying to shutdown gracefully")
|
||||||
|
|
||||||
|
if config.ErupeConfig.Channel.Enabled {
|
||||||
for _, c := range channels {
|
for _, c := range channels {
|
||||||
c.Shutdown()
|
c.Shutdown()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.ErupeConfig.Sign.Enabled {
|
||||||
signServer.Shutdown()
|
signServer.Shutdown()
|
||||||
|
}
|
||||||
|
|
||||||
|
if config.ErupeConfig.Entrance.Enabled {
|
||||||
entranceServer.Shutdown()
|
entranceServer.Shutdown()
|
||||||
if erupeConfig.DevModeOptions.EnableLauncherServer {
|
}
|
||||||
|
|
||||||
|
if config.ErupeConfig.Launcher.Enabled {
|
||||||
launcherServer.Shutdown()
|
launcherServer.Shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,7 +247,7 @@ func wait() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func preventClose(text string) {
|
func preventClose(text string) {
|
||||||
if erupeConfig.DisableSoftCrash {
|
if config.ErupeConfig.DisableSoftCrash {
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
fmt.Println("\nFailed to start Erupe:\n" + text)
|
fmt.Println("\nFailed to start Erupe:\n" + text)
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS sign_sessions;
|
|
||||||
DROP TABLE IF EXISTS characters;
|
|
||||||
DROP TABLE IF EXISTS users;
|
|
||||||
|
|
||||||
DROP DOMAIN IF EXISTS uint8;
|
|
||||||
DROP DOMAIN IF EXISTS uint16;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
CREATE DOMAIN uint8 AS smallint
|
|
||||||
CHECK(VALUE >= 0 AND VALUE <= 255);
|
|
||||||
|
|
||||||
CREATE DOMAIN uint16 AS integer
|
|
||||||
CHECK(VALUE >= 0 AND VALUE <= 65536);
|
|
||||||
|
|
||||||
CREATE TABLE users (
|
|
||||||
id serial NOT NULL PRIMARY KEY,
|
|
||||||
username text UNIQUE NOT NULL,
|
|
||||||
password text NOT NULL,
|
|
||||||
item_box bytea
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE characters (
|
|
||||||
id serial NOT NULL PRIMARY KEY,
|
|
||||||
user_id bigint REFERENCES users(id),
|
|
||||||
is_female boolean,
|
|
||||||
is_new_character boolean,
|
|
||||||
small_gr_level uint8,
|
|
||||||
gr_override_mode boolean,
|
|
||||||
name varchar(15),
|
|
||||||
unk_desc_string varchar(31),
|
|
||||||
gr_override_level uint16,
|
|
||||||
gr_override_unk0 uint8,
|
|
||||||
gr_override_unk1 uint8
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE sign_sessions (
|
|
||||||
id serial NOT NULL PRIMARY KEY,
|
|
||||||
user_id bigint REFERENCES users(id),
|
|
||||||
auth_token_num bigint,
|
|
||||||
auth_token_str text
|
|
||||||
);
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
ALTER TABLE characters
|
|
||||||
DROP COLUMN exp,
|
|
||||||
DROP COLUMN weapon,
|
|
||||||
DROP COLUMN last_login;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
ALTER TABLE characters
|
|
||||||
ADD COLUMN exp uint16,
|
|
||||||
ADD COLUMN weapon uint16,
|
|
||||||
ADD COLUMN last_login integer;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
ALTER TABLE characters
|
|
||||||
DROP COLUMN savedata;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
ALTER TABLE characters
|
|
||||||
ADD COLUMN savedata bytea;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
ALTER TABLE characters
|
|
||||||
DROP COLUMN decomyset,
|
|
||||||
DROP COLUMN hunternavi,
|
|
||||||
DROP COLUMN otomoairou,
|
|
||||||
DROP COLUMN partner,
|
|
||||||
DROP COLUMN platebox,
|
|
||||||
DROP COLUMN platedata,
|
|
||||||
DROP COLUMN platemyset,
|
|
||||||
DROP COLUMN rengokudata;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
ALTER TABLE characters
|
|
||||||
ADD COLUMN decomyset bytea,
|
|
||||||
ADD COLUMN hunternavi bytea,
|
|
||||||
ADD COLUMN otomoairou bytea,
|
|
||||||
ADD COLUMN partner bytea,
|
|
||||||
ADD COLUMN platebox bytea,
|
|
||||||
ADD COLUMN platedata bytea,
|
|
||||||
ADD COLUMN platemyset bytea,
|
|
||||||
ADD COLUMN trophy bytea,
|
|
||||||
ADD COLUMN rengokudata bytea;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
DROP TABLE IF EXISTS questlists;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
CREATE TABLE questlists (
|
|
||||||
ind int NOT NULL PRIMARY KEY,
|
|
||||||
questlist bytea
|
|
||||||
);
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
ALTER TABLE characters
|
|
||||||
DROP COLUMN savemercenary;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
ALTER TABLE characters
|
|
||||||
ADD COLUMN savemercenary bytea;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
DROP TABLE guild_characters;
|
|
||||||
DROP TABLE guilds;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
CREATE TABLE guilds
|
|
||||||
(
|
|
||||||
id serial NOT NULL PRIMARY KEY,
|
|
||||||
name varchar(24),
|
|
||||||
created_at timestamp DEFAULT NOW(),
|
|
||||||
leader_id int NOT NULL,
|
|
||||||
main_motto varchar(255) DEFAULT ''
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE guild_characters
|
|
||||||
(
|
|
||||||
id serial NOT NULL PRIMARY KEY,
|
|
||||||
guild_id bigint REFERENCES guilds (id),
|
|
||||||
character_id bigint REFERENCES characters (id),
|
|
||||||
joined_at timestamp DEFAULT NOW()
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE UNIQUE INDEX guild_character_unique_index ON guild_characters (character_id);
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
ALTER TABLE guilds
|
|
||||||
DROP COLUMN rp;
|
|
||||||
|
|
||||||
ALTER TABLE guild_characters
|
|
||||||
DROP COLUMN is_applicant,
|
|
||||||
DROP COLUMN is_sub_leader,
|
|
||||||
DROP COLUMN order_index;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
ALTER TABLE guild_characters
|
|
||||||
ADD COLUMN is_applicant bool NOT NULL DEFAULT false,
|
|
||||||
ADD COLUMN is_sub_leader bool NOT NULL DEFAULT false,
|
|
||||||
ADD COLUMN order_index int NOT NULL DEFAULT 1;
|
|
||||||
|
|
||||||
ALTER TABLE guilds
|
|
||||||
ADD COLUMN rp uint16 NOT NULL DEFAULT 0;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
ALTER TABLE characters
|
|
||||||
DROP COLUMN restrict_guild_scout;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
ALTER TABLE characters
|
|
||||||
ADD COLUMN restrict_guild_scout bool NOT NULL DEFAULT false;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
ALTER TABLE guilds
|
|
||||||
DROP COLUMN comment,
|
|
||||||
DROP COLUMN festival_colour,
|
|
||||||
DROP COLUMN guild_hall;
|
|
||||||
|
|
||||||
DROP TYPE festival_colour;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
CREATE TYPE festival_colour AS ENUM ('none', 'red', 'blue');
|
|
||||||
|
|
||||||
ALTER TABLE guilds
|
|
||||||
ADD COLUMN comment varchar(255) NOT NULL DEFAULT '',
|
|
||||||
ADD COLUMN festival_colour festival_colour DEFAULT 'none',
|
|
||||||
ADD COLUMN guild_hall int DEFAULT 0;
|
|
||||||
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
ALTER TABLE characters
|
|
||||||
DROP COLUMN minidata,
|
|
||||||
DROP COLUMN gacha_trial,
|
|
||||||
DROP COLUMN gacha_prem,
|
|
||||||
DROP COLUMN gacha_items,
|
|
||||||
DROP COLUMN daily_time,
|
|
||||||
DROP COLUMN frontier_points,
|
|
||||||
DROP COLUMN netcafe_points,
|
|
||||||
DROP COLUMN house_info,
|
|
||||||
DROP COLUMN login_boost,
|
|
||||||
DROP COLUMN skin_hist,
|
|
||||||
DROP COLUMN gcp;
|
|
||||||
|
|
||||||
DROP TABLE fpoint_items;
|
|
||||||
DROP TABLE gacha_shop;
|
|
||||||
DROP TABLE gacha_shop_items;
|
|
||||||
DROP TABLE lucky_box_state;
|
|
||||||
DROP TABLE stepup_state;
|
|
||||||
DROP TABLE normal_shop_items;
|
|
||||||
DROP TABLE shop_item_state;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
ALTER TABLE characters
|
|
||||||
ADD COLUMN minidata bytea,
|
|
||||||
ADD COLUMN gacha_trial int,
|
|
||||||
ADD COLUMN gacha_prem int,
|
|
||||||
ADD COLUMN gacha_items bytea,
|
|
||||||
ADD COLUMN daily_time timestamp,
|
|
||||||
ADD COLUMN frontier_points int,
|
|
||||||
ADD COLUMN netcafe_points int,
|
|
||||||
ADD COLUMN house_info bytea,
|
|
||||||
ADD COLUMN login_boost bytea,
|
|
||||||
ADD COLUMN skin_hist bytea,
|
|
||||||
ADD COLUMN kouryou_point int,
|
|
||||||
ADD COLUMN gcp int;
|
|
||||||
|
|
||||||
CREATE TABLE fpoint_items
|
|
||||||
(
|
|
||||||
hash int,
|
|
||||||
itemType uint8,
|
|
||||||
itemID uint16,
|
|
||||||
quant uint16,
|
|
||||||
itemValue uint16,
|
|
||||||
tradeType uint8
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE gacha_shop
|
|
||||||
(
|
|
||||||
hash bigint,
|
|
||||||
reqGR int,
|
|
||||||
reqHR int,
|
|
||||||
gachaName varchar(255),
|
|
||||||
gachaLink0 varchar(255),
|
|
||||||
gachaLink1 varchar(255),
|
|
||||||
gachaLink2 varchar(255),
|
|
||||||
extraIcon int,
|
|
||||||
gachaType int,
|
|
||||||
hideFlag bool
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE gacha_shop_items
|
|
||||||
(
|
|
||||||
shophash int,
|
|
||||||
entryType uint8,
|
|
||||||
itemhash int UNIQUE NOT NULL,
|
|
||||||
currType uint8,
|
|
||||||
currNumber uint16,
|
|
||||||
currQuant uint16,
|
|
||||||
percentage uint16,
|
|
||||||
rarityIcon uint8,
|
|
||||||
rollsCount uint8,
|
|
||||||
itemCount uint8,
|
|
||||||
dailyLimit uint8,
|
|
||||||
itemType int[],
|
|
||||||
itemId int[],
|
|
||||||
quantity int[]
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE lucky_box_state
|
|
||||||
(
|
|
||||||
char_id bigint REFERENCES characters (id),
|
|
||||||
shophash int UNIQUE NOT NULL,
|
|
||||||
used_itemhash int[]
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
CREATE TABLE stepup_state
|
|
||||||
(
|
|
||||||
char_id bigint REFERENCES characters (id),
|
|
||||||
shophash int UNIQUE NOT NULL,
|
|
||||||
step_progression int,
|
|
||||||
step_time timestamp
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE normal_shop_items
|
|
||||||
(
|
|
||||||
shoptype int,
|
|
||||||
shopid int,
|
|
||||||
itemhash int UNIQUE NOT NULL,
|
|
||||||
itemID uint16,
|
|
||||||
Points uint16,
|
|
||||||
TradeQuantity uint16,
|
|
||||||
rankReqLow uint16,
|
|
||||||
rankReqHigh uint16,
|
|
||||||
rankReqG uint16,
|
|
||||||
storeLevelReq uint16,
|
|
||||||
maximumQuantity uint16,
|
|
||||||
boughtQuantity uint16,
|
|
||||||
roadFloorsRequired uint16,
|
|
||||||
weeklyFatalisKills uint16
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE shop_item_state
|
|
||||||
(
|
|
||||||
char_id bigint REFERENCES characters (id),
|
|
||||||
itemhash int UNIQUE NOT NULL,
|
|
||||||
usedquantity int
|
|
||||||
);
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
DROP TABLE login_boost_state;
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
CREATE TABLE login_boost_state
|
|
||||||
(
|
|
||||||
char_id bigint REFERENCES characters (id),
|
|
||||||
week_req uint8,
|
|
||||||
week_count uint8,
|
|
||||||
available bool,
|
|
||||||
end_time int,
|
|
||||||
CONSTRAINT id_week UNIQUE(char_id, week_req)
|
|
||||||
);
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
ALTER TABLE shop_item_state DROP CONSTRAINT shop_item_state_id_itemhash;
|
|
||||||
ALTER TABLE shop_item_state ADD CONSTRAINT shop_item_state_itemhash_key UNIQUE (itemhash);
|
|
||||||
|
|
||||||
ALTER TABLE stepup_state DROP CONSTRAINT stepup_state_id_shophash;
|
|
||||||
ALTER TABLE stepup_state ADD CONSTRAINT stepup_state_shophash_key UNIQUE (shophash);
|
|
||||||
|
|
||||||
ALTER TABLE lucky_box_state DROP CONSTRAINT lucky_box_state_id_shophash;
|
|
||||||
ALTER TABLE lucky_box_state ADD CONSTRAINT lucky_box_state_shophash_key UNIQUE (shophash);
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
ALTER TABLE shop_item_state DROP CONSTRAINT shop_item_state_itemhash_key;
|
|
||||||
ALTER TABLE shop_item_state ADD CONSTRAINT shop_item_state_id_itemhash UNIQUE(char_id, itemhash);
|
|
||||||
|
|
||||||
ALTER TABLE stepup_state DROP CONSTRAINT stepup_state_shophash_key;
|
|
||||||
ALTER TABLE stepup_state ADD CONSTRAINT stepup_state_id_shophash UNIQUE(char_id, shophash);
|
|
||||||
|
|
||||||
ALTER TABLE lucky_box_state DROP CONSTRAINT lucky_box_state_shophash_key;
|
|
||||||
ALTER TABLE lucky_box_state ADD CONSTRAINT lucky_box_state_id_shophash UNIQUE(char_id, shophash);
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
ALTER TABLE guild_characters
|
|
||||||
RENAME COLUMN avoid_leadership TO is_sub_leader;
|
|
||||||
|
|
||||||
ALTER TABLE guild_characters
|
|
||||||
ADD COLUMN is_applicant bool NOT NULL DEFAULT false;
|
|
||||||
|
|
||||||
ALTER TABLE guilds
|
|
||||||
DROP COLUMN icon,
|
|
||||||
ALTER COLUMN main_motto TYPE varchar USING '',
|
|
||||||
DROP COLUMN sub_motto;
|
|
||||||
|
|
||||||
ALTER TABLE guilds
|
|
||||||
ALTER COLUMN main_motto SET DEFAULT '';
|
|
||||||
|
|
||||||
DROP TABLE guild_applications;
|
|
||||||
DROP TYPE guild_application_type;
|
|
||||||
END;
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
CREATE TYPE guild_application_type AS ENUM ('applied', 'invited');
|
|
||||||
|
|
||||||
CREATE TABLE guild_applications
|
|
||||||
(
|
|
||||||
id serial NOT NULL PRIMARY KEY,
|
|
||||||
guild_id int NOT NULL REFERENCES guilds (id),
|
|
||||||
character_id int NOT NULL REFERENCES characters (id),
|
|
||||||
actor_id int NOT NULL REFERENCES characters (id),
|
|
||||||
application_type guild_application_type NOT NULL,
|
|
||||||
created_at timestamp NOT NULL DEFAULT now(),
|
|
||||||
CONSTRAINT guild_application_character_id UNIQUE (guild_id, character_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE INDEX guild_application_type_index ON guild_applications (application_type);
|
|
||||||
|
|
||||||
ALTER TABLE guild_characters
|
|
||||||
DROP COLUMN is_applicant;
|
|
||||||
|
|
||||||
ALTER TABLE guild_characters
|
|
||||||
RENAME COLUMN is_sub_leader TO avoid_leadership;
|
|
||||||
|
|
||||||
ALTER TABLE guilds
|
|
||||||
ALTER COLUMN main_motto SET DEFAULT 0;
|
|
||||||
|
|
||||||
ALTER TABLE guilds
|
|
||||||
ADD COLUMN icon bytea,
|
|
||||||
ADD COLUMN sub_motto int DEFAULT 0,
|
|
||||||
ALTER COLUMN main_motto TYPE int USING 0;
|
|
||||||
END;
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
DROP TABLE mail;
|
|
||||||
END;
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
CREATE TABLE mail
|
|
||||||
(
|
|
||||||
id SERIAL NOT NULL PRIMARY KEY,
|
|
||||||
sender_id INT NOT NULL REFERENCES characters (id),
|
|
||||||
recipient_id INT NOT NULL REFERENCES characters (id),
|
|
||||||
subject VARCHAR NOT NULL DEFAULT '',
|
|
||||||
body VARCHAR NOT NULL DEFAULT '',
|
|
||||||
read BOOL NOT NULL DEFAULT FALSE,
|
|
||||||
attached_item_received BOOL NOT NULL DEFAULT FALSE,
|
|
||||||
attached_item INT DEFAULT NULL,
|
|
||||||
attached_item_amount INT NOT NULL DEFAULT 1,
|
|
||||||
is_guild_invite BOOL NOT NULL DEFAULT FALSE,
|
|
||||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
|
||||||
deleted BOOL NOT NULL DEFAULT FALSE
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE INDEX mail_recipient_deleted_created_id_index ON mail (recipient_id, deleted, created_at DESC, id DESC);
|
|
||||||
END;
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
DROP TABLE public.servers;
|
|
||||||
END;
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
-- Table: public.servers
|
|
||||||
|
|
||||||
-- DROP TABLE IF EXISTS public.servers;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS public.servers
|
|
||||||
(
|
|
||||||
server_id integer NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
|
|
||||||
server_name text COLLATE pg_catalog."default",
|
|
||||||
season integer,
|
|
||||||
current_players integer,
|
|
||||||
event_id integer,
|
|
||||||
event_expiration integer,
|
|
||||||
CONSTRAINT servers_pkey PRIMARY KEY (server_id)
|
|
||||||
)
|
|
||||||
|
|
||||||
TABLESPACE pg_default;
|
|
||||||
|
|
||||||
ALTER TABLE IF EXISTS public.servers
|
|
||||||
OWNER to postgres;
|
|
||||||
END;
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
DROP TABLE public.account_ban;
|
|
||||||
DROP TABLE public.account_history;
|
|
||||||
DROP TABLE public.account_moderation;
|
|
||||||
DROP TABLE public.account_sub;
|
|
||||||
END;
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS public.account_ban
|
|
||||||
(
|
|
||||||
user_id integer NOT NULL,
|
|
||||||
title text COLLATE pg_catalog."default",
|
|
||||||
reason text COLLATE pg_catalog."default",
|
|
||||||
date text COLLATE pg_catalog."default",
|
|
||||||
pass_origin text COLLATE pg_catalog."default",
|
|
||||||
pass_block text COLLATE pg_catalog."default",
|
|
||||||
CONSTRAINT ban_pkey PRIMARY KEY (user_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS public.account_history
|
|
||||||
(
|
|
||||||
report_id integer NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
|
|
||||||
user_id integer,
|
|
||||||
title text COLLATE pg_catalog."default",
|
|
||||||
reason text COLLATE pg_catalog."default",
|
|
||||||
date date,
|
|
||||||
CONSTRAINT account_history_pkey PRIMARY KEY (report_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS public.account_moderation
|
|
||||||
(
|
|
||||||
id integer NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
|
|
||||||
username text COLLATE pg_catalog."default",
|
|
||||||
password text COLLATE pg_catalog."default",
|
|
||||||
type text COLLATE pg_catalog."default",
|
|
||||||
CONSTRAINT account_moderation_pkey PRIMARY KEY (id)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS public.account_sub
|
|
||||||
(
|
|
||||||
id integer NOT NULL GENERATED BY DEFAULT AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
|
|
||||||
discord_id text COLLATE pg_catalog."default",
|
|
||||||
erupe_account text COLLATE pg_catalog."default",
|
|
||||||
erupe_password text COLLATE pg_catalog."default",
|
|
||||||
date_inscription date,
|
|
||||||
country text COLLATE pg_catalog."default",
|
|
||||||
presentation text COLLATE pg_catalog."default",
|
|
||||||
CONSTRAINT account_auth_pkey PRIMARY KEY (id)
|
|
||||||
);
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
DROP TABLE public.event_week;
|
|
||||||
END;
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS public.event_week
|
|
||||||
(
|
|
||||||
id integer NOT NULL,
|
|
||||||
event_id integer NOT NULL,
|
|
||||||
date_expiration integer NOT NULL,
|
|
||||||
CONSTRAINT event_week_pkey PRIMARY KEY (id)
|
|
||||||
);
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
DROP TABLE public.gook;
|
|
||||||
END;
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS public.gook
|
|
||||||
(
|
|
||||||
id serial NOT NULL PRIMARY KEY,
|
|
||||||
gook0 bytea,
|
|
||||||
gook1 bytea,
|
|
||||||
gook2 bytea,
|
|
||||||
gook3 bytea,
|
|
||||||
gook4 bytea,
|
|
||||||
gook5 bytea,
|
|
||||||
gook0status boolean,
|
|
||||||
gook1status boolean,
|
|
||||||
gook2status boolean,
|
|
||||||
gook3status boolean,
|
|
||||||
gook4status boolean,
|
|
||||||
gook5status boolean
|
|
||||||
);
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
DROP TABLE public.history;
|
|
||||||
END;
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
BEGIN;
|
|
||||||
|
|
||||||
CREATE TABLE IF NOT EXISTS public.history
|
|
||||||
(
|
|
||||||
user_id integer,
|
|
||||||
admin_id integer,
|
|
||||||
report_id integer NOT NULL,
|
|
||||||
title text COLLATE pg_catalog."default",
|
|
||||||
reason text COLLATE pg_catalog."default",
|
|
||||||
CONSTRAINT history_pkey PRIMARY KEY (report_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
END;
|
|
||||||
@@ -1,8 +1,4 @@
|
|||||||
package clientctx
|
package clientctx
|
||||||
|
|
||||||
import "erupe-ce/common/stringsupport"
|
|
||||||
|
|
||||||
// ClientContext holds contextual data required for packet encoding/decoding.
|
// ClientContext holds contextual data required for packet encoding/decoding.
|
||||||
type ClientContext struct {
|
type ClientContext struct{} // Unused
|
||||||
StrConv *stringsupport.StringConverter
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ type MsgMhfEnumerateGuild struct {
|
|||||||
AckHandle uint32
|
AckHandle uint32
|
||||||
Type EnumerateGuildType
|
Type EnumerateGuildType
|
||||||
Page uint8
|
Page uint8
|
||||||
|
Sorting bool
|
||||||
RawDataPayload []byte
|
RawDataPayload []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,6 +46,8 @@ func (m *MsgMhfEnumerateGuild) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Cli
|
|||||||
m.AckHandle = bf.ReadUint32()
|
m.AckHandle = bf.ReadUint32()
|
||||||
m.Type = EnumerateGuildType(bf.ReadUint8())
|
m.Type = EnumerateGuildType(bf.ReadUint8())
|
||||||
m.Page = bf.ReadUint8()
|
m.Page = bf.ReadUint8()
|
||||||
|
m.Sorting = bf.ReadBool()
|
||||||
|
_ = bf.ReadUint8()
|
||||||
m.RawDataPayload = bf.DataFromCurrent()
|
m.RawDataPayload = bf.DataFromCurrent()
|
||||||
bf.Seek(-2, io.SeekEnd)
|
bf.Seek(-2, io.SeekEnd)
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -29,8 +29,10 @@ func (m *MsgMhfEnumerateHouse) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Cli
|
|||||||
m.CharID = bf.ReadUint32()
|
m.CharID = bf.ReadUint32()
|
||||||
m.Method = bf.ReadUint8()
|
m.Method = bf.ReadUint8()
|
||||||
m.Unk = bf.ReadUint16()
|
m.Unk = bf.ReadUint16()
|
||||||
_ = bf.ReadUint8() // len
|
lenName := bf.ReadUint8()
|
||||||
|
if lenName > 0 {
|
||||||
m.Name = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes())
|
m.Name = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes())
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,13 +3,17 @@ package mhfpacket
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfGetGemInfo represents the MSG_MHF_GET_GEM_INFO
|
// MsgMhfGetGemInfo represents the MSG_MHF_GET_GEM_INFO
|
||||||
type MsgMhfGetGemInfo struct{}
|
type MsgMhfGetGemInfo struct {
|
||||||
|
AckHandle uint32
|
||||||
|
Unk uint32
|
||||||
|
Unk1 []byte
|
||||||
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
func (m *MsgMhfGetGemInfo) Opcode() network.PacketID {
|
func (m *MsgMhfGetGemInfo) Opcode() network.PacketID {
|
||||||
@@ -18,7 +22,10 @@ func (m *MsgMhfGetGemInfo) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfGetGemInfo) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfGetGemInfo) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
return errors.New("NOT IMPLEMENTED")
|
m.AckHandle = bf.ReadUint32()
|
||||||
|
m.Unk = bf.ReadUint32()
|
||||||
|
m.Unk1 = bf.ReadBytes(24)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build builds a binary packet from the current data.
|
// Build builds a binary packet from the current data.
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ package mhfpacket
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The server sends different responses based on these values.
|
// The server sends different responses based on these values.
|
||||||
@@ -13,7 +13,7 @@ const (
|
|||||||
TowerInfoTypeUnk0 = iota
|
TowerInfoTypeUnk0 = iota
|
||||||
TowerInfoTypeTowerRankPoint
|
TowerInfoTypeTowerRankPoint
|
||||||
TowerInfoTypeGetOwnTowerSkill
|
TowerInfoTypeGetOwnTowerSkill
|
||||||
TowerInfoTypeUnk3
|
TowerInfoTypeGetOwnTowerLevelV3
|
||||||
TowerInfoTypeTowerTouhaHistory
|
TowerInfoTypeTowerTouhaHistory
|
||||||
TowerInfoTypeUnk5
|
TowerInfoTypeUnk5
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,15 +3,16 @@ package mhfpacket
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfGuildHuntdata represents the MSG_MHF_GUILD_HUNTDATA
|
// MsgMhfGuildHuntdata represents the MSG_MHF_GUILD_HUNTDATA
|
||||||
type MsgMhfGuildHuntdata struct{
|
type MsgMhfGuildHuntdata struct {
|
||||||
AckHandle uint32
|
AckHandle uint32
|
||||||
Unk0 uint8
|
Operation uint8
|
||||||
|
GuildID uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
@@ -22,7 +23,10 @@ func (m *MsgMhfGuildHuntdata) Opcode() network.PacketID {
|
|||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfGuildHuntdata) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfGuildHuntdata) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
m.AckHandle = bf.ReadUint32()
|
m.AckHandle = bf.ReadUint32()
|
||||||
m.Unk0 = bf.ReadUint8()
|
m.Operation = bf.ReadUint8()
|
||||||
|
if m.Operation == 1 {
|
||||||
|
m.GuildID = bf.ReadUint32()
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,13 +3,17 @@ package mhfpacket
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfInfoJoint represents the MSG_MHF_INFO_JOINT
|
// MsgMhfInfoJoint represents the MSG_MHF_INFO_JOINT
|
||||||
type MsgMhfInfoJoint struct{}
|
type MsgMhfInfoJoint struct {
|
||||||
|
AckHandle uint32
|
||||||
|
AllianceID uint32
|
||||||
|
Unk uint32
|
||||||
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
func (m *MsgMhfInfoJoint) Opcode() network.PacketID {
|
func (m *MsgMhfInfoJoint) Opcode() network.PacketID {
|
||||||
@@ -18,7 +22,10 @@ func (m *MsgMhfInfoJoint) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfInfoJoint) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfInfoJoint) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
return errors.New("NOT IMPLEMENTED")
|
m.AckHandle = bf.ReadUint32()
|
||||||
|
m.AllianceID = bf.ReadUint32()
|
||||||
|
m.Unk = bf.ReadUint32()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build builds a binary packet from the current data.
|
// Build builds a binary packet from the current data.
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ package mhfpacket
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
type OperateGuildAction uint8
|
type OperateGuildAction uint8
|
||||||
@@ -28,9 +28,13 @@ const (
|
|||||||
OPERATE_GUILD_CHANGE_PUGI_1 = 0x0f
|
OPERATE_GUILD_CHANGE_PUGI_1 = 0x0f
|
||||||
OPERATE_GUILD_CHANGE_PUGI_2 = 0x10
|
OPERATE_GUILD_CHANGE_PUGI_2 = 0x10
|
||||||
OPERATE_GUILD_CHANGE_PUGI_3 = 0x11
|
OPERATE_GUILD_CHANGE_PUGI_3 = 0x11
|
||||||
// pugi something
|
OPERATE_GUILD_UNLOCK_OUTFIT = 0x12
|
||||||
|
// 0x13 Unk
|
||||||
|
// 0x14 Unk
|
||||||
OPERATE_GUILD_DONATE_EVENT = 0x15
|
OPERATE_GUILD_DONATE_EVENT = 0x15
|
||||||
// pugi something
|
OPERATE_GUILD_EVENT_EXCHANGE = 0x16
|
||||||
|
// 0x17 Unk
|
||||||
|
// 0x18 Unk
|
||||||
OPERATE_GUILD_CHANGE_DIVA_PUGI_1 = 0x19
|
OPERATE_GUILD_CHANGE_DIVA_PUGI_1 = 0x19
|
||||||
OPERATE_GUILD_CHANGE_DIVA_PUGI_2 = 0x1a
|
OPERATE_GUILD_CHANGE_DIVA_PUGI_2 = 0x1a
|
||||||
OPERATE_GUILD_CHANGE_DIVA_PUGI_3 = 0x1b
|
OPERATE_GUILD_CHANGE_DIVA_PUGI_3 = 0x1b
|
||||||
@@ -41,7 +45,8 @@ type MsgMhfOperateGuild struct {
|
|||||||
AckHandle uint32
|
AckHandle uint32
|
||||||
GuildID uint32
|
GuildID uint32
|
||||||
Action OperateGuildAction
|
Action OperateGuildAction
|
||||||
UnkData []byte
|
Data1 *byteframe.ByteFrame
|
||||||
|
Data2 *byteframe.ByteFrame
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
@@ -54,8 +59,9 @@ func (m *MsgMhfOperateGuild) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Clien
|
|||||||
m.AckHandle = bf.ReadUint32()
|
m.AckHandle = bf.ReadUint32()
|
||||||
m.GuildID = bf.ReadUint32()
|
m.GuildID = bf.ReadUint32()
|
||||||
m.Action = OperateGuildAction(bf.ReadUint8())
|
m.Action = OperateGuildAction(bf.ReadUint8())
|
||||||
m.UnkData = bf.DataFromCurrent()
|
dataLen := uint(bf.ReadUint8())
|
||||||
bf.Seek(int64(len(bf.Data()) - 2), 0)
|
m.Data1 = byteframe.NewByteFrameFromBytes(bf.ReadBytes(4))
|
||||||
|
m.Data2 = byteframe.NewByteFrameFromBytes(bf.ReadBytes(dataLen))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ package mhfpacket
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
type OperateJointAction uint8
|
type OperateJointAction uint8
|
||||||
@@ -22,7 +22,7 @@ type MsgMhfOperateJoint struct {
|
|||||||
AllianceID uint32
|
AllianceID uint32
|
||||||
GuildID uint32
|
GuildID uint32
|
||||||
Action OperateJointAction
|
Action OperateJointAction
|
||||||
UnkData []byte
|
UnkData *byteframe.ByteFrame
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
@@ -36,8 +36,8 @@ func (m *MsgMhfOperateJoint) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Clien
|
|||||||
m.AllianceID = bf.ReadUint32()
|
m.AllianceID = bf.ReadUint32()
|
||||||
m.GuildID = bf.ReadUint32()
|
m.GuildID = bf.ReadUint32()
|
||||||
m.Action = OperateJointAction(bf.ReadUint8())
|
m.Action = OperateJointAction(bf.ReadUint8())
|
||||||
m.UnkData = bf.DataFromCurrent()
|
m.UnkData = byteframe.NewByteFrameFromBytes(bf.DataFromCurrent())
|
||||||
bf.Seek(int64(len(bf.Data()) - 2), 0)
|
bf.Seek(int64(len(bf.Data())-2), 0)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,15 +3,17 @@ package mhfpacket
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TerminalLogEntry represents an entry in the MSG_SYS_TERMINAL_LOG packet.
|
// TerminalLogEntry represents an entry in the MSG_SYS_TERMINAL_LOG packet.
|
||||||
type TerminalLogEntry struct {
|
type TerminalLogEntry struct {
|
||||||
// Unknown fields
|
Index uint32
|
||||||
U0, U1, U2, U3, U4, U5, U6, U7, U8 uint32
|
Type1 uint8
|
||||||
|
Type2 uint8
|
||||||
|
Data []int16
|
||||||
}
|
}
|
||||||
|
|
||||||
// MsgSysTerminalLog represents the MSG_SYS_TERMINAL_LOG
|
// MsgSysTerminalLog represents the MSG_SYS_TERMINAL_LOG
|
||||||
@@ -37,15 +39,12 @@ func (m *MsgSysTerminalLog) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Client
|
|||||||
|
|
||||||
for i := 0; i < int(m.EntryCount); i++ {
|
for i := 0; i < int(m.EntryCount); i++ {
|
||||||
e := &TerminalLogEntry{}
|
e := &TerminalLogEntry{}
|
||||||
e.U0 = bf.ReadUint32()
|
e.Index = bf.ReadUint32()
|
||||||
e.U1 = bf.ReadUint32()
|
e.Type1 = bf.ReadUint8()
|
||||||
e.U2 = bf.ReadUint32()
|
e.Type2 = bf.ReadUint8()
|
||||||
e.U3 = bf.ReadUint32()
|
for j := 0; j < 15; j++ {
|
||||||
e.U4 = bf.ReadUint32()
|
e.Data = append(e.Data, bf.ReadInt16())
|
||||||
e.U5 = bf.ReadUint32()
|
}
|
||||||
e.U6 = bf.ReadUint32()
|
|
||||||
e.U7 = bf.ReadUint32()
|
|
||||||
e.U8 = bf.ReadUint32()
|
|
||||||
m.Entries = append(m.Entries, e)
|
m.Entries = append(m.Entries, e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package mhfpacket
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
ps "erupe-ce/common/pascalstring"
|
||||||
|
"golang.org/x/exp/slices"
|
||||||
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
"erupe-ce/network"
|
"erupe-ce/network"
|
||||||
@@ -34,6 +36,12 @@ type ClientRight struct {
|
|||||||
Timestamp uint32
|
Timestamp uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Course struct {
|
||||||
|
Aliases []string
|
||||||
|
ID uint16
|
||||||
|
Value uint32
|
||||||
|
}
|
||||||
|
|
||||||
// MsgSysUpdateRight represents the MSG_SYS_UPDATE_RIGHT
|
// MsgSysUpdateRight represents the MSG_SYS_UPDATE_RIGHT
|
||||||
type MsgSysUpdateRight struct {
|
type MsgSysUpdateRight struct {
|
||||||
ClientRespAckHandle uint32 // If non-0, requests the client to send back a MSG_SYS_ACK packet with this value.
|
ClientRespAckHandle uint32 // If non-0, requests the client to send back a MSG_SYS_ACK packet with this value.
|
||||||
@@ -63,9 +71,40 @@ func (m *MsgSysUpdateRight) Build(bf *byteframe.ByteFrame, ctx *clientctx.Client
|
|||||||
bf.WriteUint16(v.Unk0)
|
bf.WriteUint16(v.Unk0)
|
||||||
bf.WriteUint32(v.Timestamp)
|
bf.WriteUint32(v.Timestamp)
|
||||||
}
|
}
|
||||||
|
ps.Uint16(bf, "", false) // update client login token / password in the game's launcherstate struct
|
||||||
bf.WriteUint16(m.UnkSize) // String of upto 0x800 bytes, update client login token / password in the game's launcherstate struct.
|
|
||||||
//bf.WriteBytes(m.UpdatedClientLoginToken)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Courses() []Course {
|
||||||
|
var courses = []Course{
|
||||||
|
{[]string{"Trial", "TL"}, 1, 0x00000002},
|
||||||
|
{[]string{"HunterLife", "HL"}, 2, 0x00000004},
|
||||||
|
{[]string{"ExtraA", "Extra", "EX"}, 3, 0x00000008},
|
||||||
|
{[]string{"ExtraB"}, 4, 0x00000010},
|
||||||
|
{[]string{"Mobile"}, 5, 0x00000020},
|
||||||
|
{[]string{"Premium"}, 6, 0x00000040},
|
||||||
|
{[]string{"Pallone"}, 7, 0x00000080},
|
||||||
|
{[]string{"Assist", "Legend", "Rasta"}, 8, 0x00000100}, // Legend
|
||||||
|
{[]string{"Netcafe", "N", "Cafe"}, 9, 0x00000200},
|
||||||
|
{[]string{"Hiden", "Secret"}, 10, 0x00000400}, // Secret
|
||||||
|
{[]string{"HunterSupport", "HunterAid", "Support", "Royal", "Aid"}, 11, 0x00000800}, // Royal
|
||||||
|
{[]string{"NetcafeBoost", "NBoost", "Boost"}, 12, 0x00001000},
|
||||||
|
}
|
||||||
|
return courses
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetCourseStruct returns a slice of Course(s) from a rights integer
|
||||||
|
func GetCourseStruct(rights uint32) []Course {
|
||||||
|
var resp []Course
|
||||||
|
s := Courses()
|
||||||
|
slices.SortStableFunc(s, func(i, j Course) bool {
|
||||||
|
return i.ID > j.ID
|
||||||
|
})
|
||||||
|
for _, course := range s {
|
||||||
|
if rights-course.Value < 0x80000000 {
|
||||||
|
resp = append(resp, course)
|
||||||
|
rights -= course.Value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return resp
|
||||||
|
}
|
||||||
|
|||||||
9
patch-schema/active-feature.sql
Normal file
9
patch-schema/active-feature.sql
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
BEGIN;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS public.feature_weapon
|
||||||
|
(
|
||||||
|
start_time timestamp without time zone NOT NULL,
|
||||||
|
featured integer NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
END;
|
||||||
15
patch-schema/guild-poogie-outfits.sql
Normal file
15
patch-schema/guild-poogie-outfits.sql
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
BEGIN;
|
||||||
|
|
||||||
|
ALTER TABLE IF EXISTS public.guilds
|
||||||
|
ADD COLUMN IF NOT EXISTS pugi_outfit_1 int NOT NULL DEFAULT 0;
|
||||||
|
|
||||||
|
ALTER TABLE IF EXISTS public.guilds
|
||||||
|
ADD COLUMN IF NOT EXISTS pugi_outfit_2 int NOT NULL DEFAULT 0;
|
||||||
|
|
||||||
|
ALTER TABLE IF EXISTS public.guilds
|
||||||
|
ADD COLUMN IF NOT EXISTS pugi_outfit_3 int NOT NULL DEFAULT 0;
|
||||||
|
|
||||||
|
ALTER TABLE IF EXISTS public.guilds
|
||||||
|
ADD COLUMN IF NOT EXISTS pugi_outfits int NOT NULL DEFAULT 0;
|
||||||
|
|
||||||
|
END;
|
||||||
6
patch-schema/netcafe-2.sql
Normal file
6
patch-schema/netcafe-2.sql
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
BEGIN;
|
||||||
|
|
||||||
|
ALTER TABLE IF EXISTS public.characters
|
||||||
|
ADD COLUMN cafe_reset timestamp without time zone;
|
||||||
|
|
||||||
|
END;
|
||||||
@@ -27,14 +27,4 @@ CREATE TABLE IF NOT EXISTS public.cafe_accepted
|
|||||||
character_id integer NOT NULL
|
character_id integer NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
INSERT INTO public.cafebonus (time_req, item_type, item_id, quantity)
|
|
||||||
VALUES
|
|
||||||
(1800, 17, 0, 250),
|
|
||||||
(3600, 17, 0, 500),
|
|
||||||
(7200, 17, 0, 1000),
|
|
||||||
(10800, 17, 0, 1500),
|
|
||||||
(18000, 17, 0, 1750),
|
|
||||||
(28800, 17, 0, 3000),
|
|
||||||
(43200, 17, 0, 4000);
|
|
||||||
|
|
||||||
END;
|
END;
|
||||||
37
patch-schema/persistent-house.sql
Normal file
37
patch-schema/persistent-house.sql
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
BEGIN;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS public.user_binary
|
||||||
|
(
|
||||||
|
id serial NOT NULL PRIMARY KEY,
|
||||||
|
type2 bytea,
|
||||||
|
type3 bytea,
|
||||||
|
house_tier bytea,
|
||||||
|
house_state int,
|
||||||
|
house_password text,
|
||||||
|
house_data bytea,
|
||||||
|
house_furniture bytea,
|
||||||
|
bookshelf bytea,
|
||||||
|
gallery bytea,
|
||||||
|
tore bytea,
|
||||||
|
garden bytea,
|
||||||
|
mission bytea
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Create entries for existing users
|
||||||
|
INSERT INTO public.user_binary (id) SELECT c.id FROM characters c;
|
||||||
|
|
||||||
|
-- Copy existing data
|
||||||
|
UPDATE public.user_binary
|
||||||
|
SET house_furniture = (SELECT house FROM characters WHERE user_binary.id = characters.id);
|
||||||
|
|
||||||
|
UPDATE public.user_binary
|
||||||
|
SET mission = (SELECT trophy FROM characters WHERE user_binary.id = characters.id);
|
||||||
|
|
||||||
|
-- Drop old data location
|
||||||
|
ALTER TABLE public.characters
|
||||||
|
DROP COLUMN house;
|
||||||
|
|
||||||
|
ALTER TABLE public.characters
|
||||||
|
DROP COLUMN trophy;
|
||||||
|
|
||||||
|
END;
|
||||||
23
patch-schema/servers_info.sql
Normal file
23
patch-schema/servers_info.sql
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
--adds world_name and land columns
|
||||||
|
BEGIN;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS public.servers
|
||||||
|
(
|
||||||
|
server_id integer NOT NULL,
|
||||||
|
season integer NOT NULL,
|
||||||
|
current_players integer NOT NULL,
|
||||||
|
world_name text COLLATE pg_catalog."default",
|
||||||
|
world_description text,
|
||||||
|
land integer
|
||||||
|
);
|
||||||
|
|
||||||
|
ALTER TABLE public.servers
|
||||||
|
ADD COLUMN IF NOT EXISTS land integer;
|
||||||
|
|
||||||
|
ALTER TABLE public.servers
|
||||||
|
ADD COLUMN IF NOT EXISTS world_name text COLLATE pg_catalog."default";
|
||||||
|
|
||||||
|
ALTER TABLE public.servers
|
||||||
|
ADD COLUMN IF NOT EXISTS world_description text;
|
||||||
|
|
||||||
|
END;
|
||||||
@@ -6,7 +6,6 @@ import (
|
|||||||
"erupe-ce/common/stringsupport"
|
"erupe-ce/common/stringsupport"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -74,26 +73,16 @@ func doAckSimpleFail(s *Session, ackHandle uint32, data []byte) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func updateRights(s *Session) {
|
func updateRights(s *Session) {
|
||||||
s.rights = uint32(0x0E)
|
rightsInt := uint32(0x0E)
|
||||||
s.server.db.QueryRow("SELECT rights FROM users u INNER JOIN characters c ON u.id = c.user_id WHERE c.id = $1", s.charID).Scan(&s.rights)
|
s.server.db.QueryRow("SELECT rights FROM users u INNER JOIN characters c ON u.id = c.user_id WHERE c.id = $1", s.charID).Scan(&rightsInt)
|
||||||
|
s.courses = mhfpacket.GetCourseStruct(rightsInt)
|
||||||
rights := make([]mhfpacket.ClientRight, 0)
|
rights := []mhfpacket.ClientRight{{1, 0, 0}}
|
||||||
tempRights := s.rights
|
for _, course := range s.courses {
|
||||||
for i := 30; i > 0; i-- {
|
rights = append(rights, mhfpacket.ClientRight{ID: course.ID, Timestamp: 0x70DB59F0})
|
||||||
right := uint32(math.Pow(2, float64(i)))
|
|
||||||
if tempRights-right < 0x80000000 {
|
|
||||||
if i == 1 {
|
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
rights = append(rights, mhfpacket.ClientRight{ID: uint16(i), Timestamp: 0x70DB59F0})
|
|
||||||
tempRights -= right
|
|
||||||
}
|
|
||||||
}
|
|
||||||
rights = append(rights, mhfpacket.ClientRight{ID: 1, Timestamp: 0})
|
|
||||||
|
|
||||||
update := &mhfpacket.MsgSysUpdateRight{
|
update := &mhfpacket.MsgSysUpdateRight{
|
||||||
ClientRespAckHandle: 0,
|
ClientRespAckHandle: 0,
|
||||||
Bitfield: s.rights,
|
Bitfield: rightsInt,
|
||||||
Rights: rights,
|
Rights: rights,
|
||||||
UnkSize: 0,
|
UnkSize: 0,
|
||||||
}
|
}
|
||||||
@@ -118,9 +107,14 @@ func handleMsgSysAck(s *Session, p mhfpacket.MHFPacket) {}
|
|||||||
|
|
||||||
func handleMsgSysTerminalLog(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgSysTerminalLog(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgSysTerminalLog)
|
pkt := p.(*mhfpacket.MsgSysTerminalLog)
|
||||||
|
for i := range pkt.Entries {
|
||||||
|
s.server.logger.Info("SysTerminalLog",
|
||||||
|
zap.Uint8("Type1", pkt.Entries[i].Type1),
|
||||||
|
zap.Uint8("Type2", pkt.Entries[i].Type2),
|
||||||
|
zap.Int16s("Data", pkt.Entries[i].Data))
|
||||||
|
}
|
||||||
resp := byteframe.NewByteFrame()
|
resp := byteframe.NewByteFrame()
|
||||||
|
resp.WriteUint32(pkt.LogID + 1) // LogID to use for requests after this.
|
||||||
resp.WriteUint32(0x98bd51a9) // LogID to use for requests after this.
|
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, resp.Data())
|
doAckSimpleSucceed(s, pkt.AckHandle, resp.Data())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,11 +171,29 @@ func handleMsgSysLogout(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func logoutPlayer(s *Session) {
|
func logoutPlayer(s *Session) {
|
||||||
|
s.server.Lock()
|
||||||
if _, exists := s.server.sessions[s.rawConn]; exists {
|
if _, exists := s.server.sessions[s.rawConn]; exists {
|
||||||
delete(s.server.sessions, s.rawConn)
|
delete(s.server.sessions, s.rawConn)
|
||||||
|
}
|
||||||
s.rawConn.Close()
|
s.rawConn.Close()
|
||||||
} else {
|
s.server.Unlock()
|
||||||
return // Prevent re-running logout logic on real logouts
|
|
||||||
|
for _, stage := range s.server.stages {
|
||||||
|
// Tell sessions registered to disconnecting players quest to unregister
|
||||||
|
if stage.host != nil && stage.host.charID == s.charID {
|
||||||
|
for _, sess := range s.server.sessions {
|
||||||
|
for rSlot := range stage.reservedClientSlots {
|
||||||
|
if sess.charID == rSlot && sess.stage != nil && sess.stage.id[3:5] != "Qs" {
|
||||||
|
sess.QueueSendMHF(&mhfpacket.MsgSysStageDestruct{})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for session := range stage.clients {
|
||||||
|
if session.charID == s.charID {
|
||||||
|
delete(stage.clients, session)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := s.server.db.Exec("UPDATE sign_sessions SET server_id=NULL, char_id=NULL WHERE token=$1", s.token)
|
_, err := s.server.db.Exec("UPDATE sign_sessions SET server_id=NULL, char_id=NULL WHERE token=$1", s.token)
|
||||||
@@ -201,7 +213,7 @@ func logoutPlayer(s *Session) {
|
|||||||
timePlayed += sessionTime
|
timePlayed += sessionTime
|
||||||
|
|
||||||
var rpGained int
|
var rpGained int
|
||||||
if s.rights >= 0x40000000 { // N Course
|
if s.FindCourse("Netcafe").ID != 0 {
|
||||||
rpGained = timePlayed / 900
|
rpGained = timePlayed / 900
|
||||||
timePlayed = timePlayed % 900
|
timePlayed = timePlayed % 900
|
||||||
} else {
|
} else {
|
||||||
@@ -235,17 +247,11 @@ func logoutPlayer(s *Session) {
|
|||||||
|
|
||||||
saveData, err := GetCharacterSaveData(s, s.charID)
|
saveData, err := GetCharacterSaveData(s, s.charID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
s.logger.Error("Failed to get savedata")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
saveData.RP += uint16(rpGained)
|
saveData.RP += uint16(rpGained)
|
||||||
transaction, err := s.server.db.Begin()
|
saveData.Save(s)
|
||||||
err = saveData.Save(s, transaction)
|
|
||||||
if err != nil {
|
|
||||||
transaction.Rollback()
|
|
||||||
panic(err)
|
|
||||||
} else {
|
|
||||||
transaction.Commit()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgSysSetStatus(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgSysSetStatus(s *Session, p mhfpacket.MHFPacket) {}
|
||||||
@@ -754,6 +760,7 @@ func handleMsgMhfUpdateGuacot(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
bf.WriteUint8(gook.NameLen)
|
bf.WriteUint8(gook.NameLen)
|
||||||
bf.WriteBytes(gook.Name)
|
bf.WriteBytes(gook.Name)
|
||||||
s.server.db.Exec(fmt.Sprintf("UPDATE gook SET gook%d=$1 WHERE id=$2", gook.Index), bf.Data(), s.charID)
|
s.server.db.Exec(fmt.Sprintf("UPDATE gook SET gook%d=$1 WHERE id=$2", gook.Index), bf.Data(), s.charID)
|
||||||
|
dumpSaveData(s, bf.Data(), fmt.Sprintf("goocoo-%d", gook.Index))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
||||||
@@ -1749,6 +1756,7 @@ func handleMsgMhfUpdateEquipSkinHist(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
byteInd := (bit / 8)
|
byteInd := (bit / 8)
|
||||||
bitInByte := bit % 8
|
bitInByte := bit % 8
|
||||||
data[startByte+byteInd] |= bits.Reverse8((1 << uint(bitInByte)))
|
data[startByte+byteInd] |= bits.Reverse8((1 << uint(bitInByte)))
|
||||||
|
dumpSaveData(s, data, "skinhist")
|
||||||
_, err = s.server.db.Exec("UPDATE characters SET skin_hist=$1 WHERE id=$2", data, s.charID)
|
_, err = s.server.db.Exec("UPDATE characters SET skin_hist=$1 WHERE id=$2", data, s.charID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@@ -1758,8 +1766,9 @@ func handleMsgMhfUpdateEquipSkinHist(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
|
|
||||||
func handleMsgMhfGetUdShopCoin(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfGetUdShopCoin(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfGetUdShopCoin)
|
pkt := p.(*mhfpacket.MsgMhfGetUdShopCoin)
|
||||||
data, _ := hex.DecodeString("0000000000000001")
|
bf := byteframe.NewByteFrame()
|
||||||
doAckBufSucceed(s, pkt.AckHandle, data)
|
bf.WriteUint32(0)
|
||||||
|
doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfUseUdShopCoin(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgMhfUseUdShopCoin(s *Session, p mhfpacket.MHFPacket) {}
|
||||||
@@ -1778,6 +1787,7 @@ func handleMsgMhfGetEnhancedMinidata(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
|
|
||||||
func handleMsgMhfSetEnhancedMinidata(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfSetEnhancedMinidata(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfSetEnhancedMinidata)
|
pkt := p.(*mhfpacket.MsgMhfSetEnhancedMinidata)
|
||||||
|
dumpSaveData(s, pkt.RawDataPayload, "minidata")
|
||||||
_, err := s.server.db.Exec("UPDATE characters SET minidata=$1 WHERE id=$2", pkt.RawDataPayload, s.charID)
|
_, err := s.server.db.Exec("UPDATE characters SET minidata=$1 WHERE id=$2", pkt.RawDataPayload, s.charID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Fatal("Failed to update minidata in db", zap.Error(err))
|
s.logger.Fatal("Failed to update minidata in db", zap.Error(err))
|
||||||
@@ -1792,9 +1802,7 @@ func handleMsgMhfGetLobbyCrowd(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
// It can be worried about later if we ever get to the point where there are
|
// It can be worried about later if we ever get to the point where there are
|
||||||
// full servers to actually need to migrate people from and empty ones to
|
// full servers to actually need to migrate people from and empty ones to
|
||||||
pkt := p.(*mhfpacket.MsgMhfGetLobbyCrowd)
|
pkt := p.(*mhfpacket.MsgMhfGetLobbyCrowd)
|
||||||
blankData := make([]byte, 0x320)
|
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 0x320))
|
||||||
doAckBufSucceed(s, pkt.AckHandle, blankData)
|
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfGetTrendWeapon(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfGetTrendWeapon(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
ps "erupe-ce/common/pascalstring"
|
ps "erupe-ce/common/pascalstring"
|
||||||
"erupe-ce/network/mhfpacket"
|
"erupe-ce/network/mhfpacket"
|
||||||
|
"fmt"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"io"
|
"io"
|
||||||
"time"
|
"time"
|
||||||
@@ -71,15 +72,22 @@ func handleMsgMhfGetCafeDuration(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
pkt := p.(*mhfpacket.MsgMhfGetCafeDuration)
|
pkt := p.(*mhfpacket.MsgMhfGetCafeDuration)
|
||||||
bf := byteframe.NewByteFrame()
|
bf := byteframe.NewByteFrame()
|
||||||
|
|
||||||
|
var cafeReset time.Time
|
||||||
|
err := s.server.db.QueryRow(`SELECT cafe_reset FROM characters WHERE id=$1`, s.charID).Scan(&cafeReset)
|
||||||
|
if Time_Current_Adjusted().After(cafeReset) {
|
||||||
|
cafeReset = TimeWeekNext()
|
||||||
|
s.server.db.Exec(`UPDATE characters SET cafe_time=0, cafe_reset=$1 WHERE id=$2; DELETE FROM cafe_accepted WHERE character_id=$2`, cafeReset, s.charID)
|
||||||
|
}
|
||||||
|
|
||||||
var cafeTime uint32
|
var cafeTime uint32
|
||||||
err := s.server.db.QueryRow("SELECT cafe_time FROM characters WHERE id = $1", s.charID).Scan(&cafeTime)
|
err = s.server.db.QueryRow("SELECT cafe_time FROM characters WHERE id = $1", s.charID).Scan(&cafeTime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
cafeTime = uint32(Time_Current_Adjusted().Unix()) - uint32(s.sessionStart) + cafeTime
|
cafeTime = uint32(Time_Current_Adjusted().Unix()) - uint32(s.sessionStart) + cafeTime
|
||||||
bf.WriteUint32(cafeTime) // Total cafe time
|
bf.WriteUint32(cafeTime) // Total cafe time
|
||||||
bf.WriteUint16(0)
|
bf.WriteUint16(0)
|
||||||
ps.Uint16(bf, "Resets at next maintenance", true)
|
ps.Uint16(bf, fmt.Sprintf("Resets on %s %d", cafeReset.Month().String(), cafeReset.Day()), true)
|
||||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,26 @@
|
|||||||
package channelserver
|
package channelserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/hex"
|
||||||
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/config"
|
||||||
|
"erupe-ce/network/binpacket"
|
||||||
|
"erupe-ce/network/mhfpacket"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"golang.org/x/exp/slices"
|
||||||
"math"
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"erupe-ce/common/byteframe"
|
"go.uber.org/zap"
|
||||||
"erupe-ce/network/binpacket"
|
|
||||||
"erupe-ce/network/mhfpacket"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// MSG_SYS_CAST[ED]_BINARY types enum
|
// MSG_SYS_CAST[ED]_BINARY types enum
|
||||||
const (
|
const (
|
||||||
BinaryMessageTypeState = 0
|
BinaryMessageTypeState = 0
|
||||||
BinaryMessageTypeChat = 1
|
BinaryMessageTypeChat = 1
|
||||||
|
BinaryMessageTypeQuest = 2
|
||||||
BinaryMessageTypeData = 3
|
BinaryMessageTypeData = 3
|
||||||
BinaryMessageTypeMailNotify = 4
|
BinaryMessageTypeMailNotify = 4
|
||||||
BinaryMessageTypeEmote = 6
|
BinaryMessageTypeEmote = 6
|
||||||
@@ -29,6 +34,28 @@ const (
|
|||||||
BroadcastTypeWorld = 0x0a
|
BroadcastTypeWorld = 0x0a
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var commands map[string]config.Command
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
commands = make(map[string]config.Command)
|
||||||
|
zapLogger, _ := zap.NewDevelopment()
|
||||||
|
defer zapLogger.Sync()
|
||||||
|
logger := zapLogger.Named("commands")
|
||||||
|
cmds := config.ErupeConfig.Commands
|
||||||
|
for _, cmd := range cmds {
|
||||||
|
commands[cmd.Name] = cmd
|
||||||
|
if cmd.Enabled {
|
||||||
|
logger.Info(fmt.Sprintf("%s command is enabled, prefix: %s", cmd.Name, cmd.Prefix))
|
||||||
|
} else {
|
||||||
|
logger.Info(fmt.Sprintf("%s command is disabled", cmd.Name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendDisabledCommandMessage(s *Session, cmd config.Command) {
|
||||||
|
sendServerChatMessage(s, fmt.Sprintf("%s command is disabled", cmd.Name))
|
||||||
|
}
|
||||||
|
|
||||||
func sendServerChatMessage(s *Session, message string) {
|
func sendServerChatMessage(s *Session, message string) {
|
||||||
// Make the inside of the casted binary
|
// Make the inside of the casted binary
|
||||||
bf := byteframe.NewByteFrame()
|
bf := byteframe.NewByteFrame()
|
||||||
@@ -64,6 +91,18 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if s.server.erupeConfig.DevModeOptions.QuestDebugTools == true && s.server.erupeConfig.DevMode {
|
||||||
|
if pkt.BroadcastType == 0x03 && pkt.MessageType == 0x02 && len(pkt.RawDataPayload) > 32 {
|
||||||
|
// This is only correct most of the time
|
||||||
|
tmp.ReadBytes(20)
|
||||||
|
tmp.SetLE()
|
||||||
|
x := tmp.ReadFloat32()
|
||||||
|
y := tmp.ReadFloat32()
|
||||||
|
z := tmp.ReadFloat32()
|
||||||
|
s.logger.Debug("Coord", zap.Float32s("XYZ", []float32{x, y, z}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Parse out the real casted binary payload
|
// Parse out the real casted binary payload
|
||||||
var msgBinTargeted *binpacket.MsgBinTargeted
|
var msgBinTargeted *binpacket.MsgBinTargeted
|
||||||
var authorLen, msgLen uint16
|
var authorLen, msgLen uint16
|
||||||
@@ -165,8 +204,14 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
|
|
||||||
fmt.Printf("Got chat message: %+v\n", chatMessage)
|
fmt.Printf("Got chat message: %+v\n", chatMessage)
|
||||||
|
|
||||||
|
// Discord integration
|
||||||
|
if (pkt.BroadcastType == BroadcastTypeStage && s.stage.id == "sl1Ns200p0a0u0") || pkt.BroadcastType == BroadcastTypeWorld {
|
||||||
|
s.server.DiscordChannelSend(chatMessage.SenderName, chatMessage.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(chatMessage.Message, commands["Reload"].Prefix) {
|
||||||
// Flush all objects and users and reload
|
// Flush all objects and users and reload
|
||||||
if strings.HasPrefix(chatMessage.Message, "!reload") {
|
if commands["Reload"].Enabled {
|
||||||
sendServerChatMessage(s, "Reloading players...")
|
sendServerChatMessage(s, "Reloading players...")
|
||||||
var temp mhfpacket.MHFPacket
|
var temp mhfpacket.MHFPacket
|
||||||
deleteNotif := byteframe.NewByteFrame()
|
deleteNotif := byteframe.NewByteFrame()
|
||||||
@@ -223,10 +268,35 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
reloadNotif.WriteUint16(0x0010)
|
reloadNotif.WriteUint16(0x0010)
|
||||||
s.QueueSend(reloadNotif.Data())
|
s.QueueSend(reloadNotif.Data())
|
||||||
|
} else {
|
||||||
|
sendDisabledCommandMessage(s, commands["Reload"])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(chatMessage.Message, commands["KeyQuest"].Prefix) {
|
||||||
|
if commands["KeyQuest"].Enabled {
|
||||||
|
if strings.HasPrefix(chatMessage.Message, "!kqf get") {
|
||||||
|
sendServerChatMessage(s, fmt.Sprintf("KQF: %x", s.kqf))
|
||||||
|
} else if strings.HasPrefix(chatMessage.Message, "!kqf set") {
|
||||||
|
var hexs string
|
||||||
|
n, numerr := fmt.Sscanf(chatMessage.Message, "!kqf set %s", &hexs)
|
||||||
|
if numerr != nil || n != 1 || len(hexs) != 16 {
|
||||||
|
sendServerChatMessage(s, "Error in command. Format: !kqf set xxxxxxxxxxxxxxxx")
|
||||||
|
} else {
|
||||||
|
hexd, _ := hex.DecodeString(hexs)
|
||||||
|
s.kqf = hexd
|
||||||
|
s.kqfOverride = true
|
||||||
|
sendServerChatMessage(s, "KQF set, please switch Land/World")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sendDisabledCommandMessage(s, commands["KeyQuest"])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(chatMessage.Message, commands["Rights"].Prefix) {
|
||||||
// Set account rights
|
// Set account rights
|
||||||
if strings.HasPrefix(chatMessage.Message, "!rights") {
|
if commands["Rights"].Enabled {
|
||||||
var v uint32
|
var v uint32
|
||||||
n, err := fmt.Sscanf(chatMessage.Message, "!rights %d", &v)
|
n, err := fmt.Sscanf(chatMessage.Message, "!rights %d", &v)
|
||||||
if err != nil || n != 1 {
|
if err != nil || n != 1 {
|
||||||
@@ -237,15 +307,60 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
sendServerChatMessage(s, fmt.Sprintf("Set rights integer: %d", v))
|
sendServerChatMessage(s, fmt.Sprintf("Set rights integer: %d", v))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
sendDisabledCommandMessage(s, commands["Rights"])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Discord integration
|
if strings.HasPrefix(chatMessage.Message, commands["Course"].Prefix) {
|
||||||
if (pkt.BroadcastType == BroadcastTypeStage && s.stage.id == "sl1Ns200p0a0u0") || pkt.BroadcastType == BroadcastTypeWorld {
|
if commands["Course"].Enabled {
|
||||||
s.server.DiscordChannelSend(chatMessage.SenderName, chatMessage.Message)
|
var name string
|
||||||
|
n, err := fmt.Sscanf(chatMessage.Message, "!course %s", &name)
|
||||||
|
if err != nil || n != 1 {
|
||||||
|
sendServerChatMessage(s, "Error in command. Format: !course <name>")
|
||||||
|
} else {
|
||||||
|
name = strings.ToLower(name)
|
||||||
|
for _, course := range mhfpacket.Courses() {
|
||||||
|
for _, alias := range course.Aliases {
|
||||||
|
if strings.ToLower(name) == strings.ToLower(alias) {
|
||||||
|
if slices.Contains(s.server.erupeConfig.Courses, config.Course{Name: course.Aliases[0], Enabled: true}) {
|
||||||
|
if s.FindCourse(name).Value != 0 {
|
||||||
|
ei := slices.IndexFunc(s.courses, func(c mhfpacket.Course) bool {
|
||||||
|
for _, alias := range c.Aliases {
|
||||||
|
if strings.ToLower(name) == strings.ToLower(alias) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
if ei != -1 {
|
||||||
|
s.courses = append(s.courses[:ei], s.courses[ei+1:]...)
|
||||||
|
sendServerChatMessage(s, fmt.Sprintf(`%s Course disabled.`, course.Aliases[0]))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
s.courses = append(s.courses, course)
|
||||||
|
sendServerChatMessage(s, fmt.Sprintf(`%s Course enabled.`, course.Aliases[0]))
|
||||||
|
}
|
||||||
|
var newInt uint32
|
||||||
|
for _, course := range s.courses {
|
||||||
|
newInt += course.Value
|
||||||
|
}
|
||||||
|
s.server.db.Exec("UPDATE users u SET rights=$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", newInt, s.charID)
|
||||||
|
updateRights(s)
|
||||||
|
} else {
|
||||||
|
sendServerChatMessage(s, fmt.Sprintf(`%s Course is locked.`, course.Aliases[0]))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sendDisabledCommandMessage(s, commands["Course"])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RAVI COMMANDS V2
|
if strings.HasPrefix(chatMessage.Message, commands["Raviente"].Prefix) {
|
||||||
if strings.HasPrefix(chatMessage.Message, "!ravi") {
|
if commands["Raviente"].Enabled {
|
||||||
if getRaviSemaphore(s) != "" {
|
if getRaviSemaphore(s) != "" {
|
||||||
s.server.raviente.Lock()
|
s.server.raviente.Lock()
|
||||||
if !strings.HasPrefix(chatMessage.Message, "!ravi ") {
|
if !strings.HasPrefix(chatMessage.Message, "!ravi ") {
|
||||||
@@ -302,10 +417,13 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
} else {
|
} else {
|
||||||
sendServerChatMessage(s, "No one has joined the Great Slaying!")
|
sendServerChatMessage(s, "No one has joined the Great Slaying!")
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
sendDisabledCommandMessage(s, commands["Raviente"])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// END RAVI COMMANDS V2
|
|
||||||
|
|
||||||
if strings.HasPrefix(chatMessage.Message, "!tele ") {
|
if strings.HasPrefix(chatMessage.Message, commands["Teleport"].Prefix) {
|
||||||
|
if commands["Teleport"].Enabled {
|
||||||
var x, y int16
|
var x, y int16
|
||||||
n, err := fmt.Sscanf(chatMessage.Message, "!tele %d %d", &x, &y)
|
n, err := fmt.Sscanf(chatMessage.Message, "!tele %d %d", &x, &y)
|
||||||
if err != nil || n != 2 {
|
if err != nil || n != 2 {
|
||||||
@@ -327,6 +445,9 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
RawDataPayload: payloadBytes,
|
RawDataPayload: payloadBytes,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
sendDisabledCommandMessage(s, commands["Teleport"])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package channelserver
|
package channelserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
|
||||||
"erupe-ce/network/mhfpacket"
|
"erupe-ce/network/mhfpacket"
|
||||||
@@ -10,120 +9,154 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
CharacterSaveRPPointer = 0x22D16
|
pointerGender = 0x81 // +1
|
||||||
|
pointerRP = 0x22D16 // +2
|
||||||
|
pointerHouseTier = 0x1FB6C // +5
|
||||||
|
pointerHouseData = 0x1FE01 // +195
|
||||||
|
pointerBookshelfData = 0x22298 // +5576
|
||||||
|
// Gallery data also exists at 0x21578, is this the contest submission?
|
||||||
|
pointerGalleryData = 0x22320 // +1748
|
||||||
|
pointerToreData = 0x1FCB4 // +240
|
||||||
|
pointerGardenData = 0x22C58 // +68
|
||||||
|
pointerWeaponType = 0x1F715 // +1
|
||||||
|
pointerWeaponID = 0x1F60A // +2
|
||||||
|
pointerHRP = 0x1FDF6 // +2
|
||||||
|
pointerGRP = 0x1FDFC // +4
|
||||||
|
pointerKQF = 0x23D20 // +8
|
||||||
)
|
)
|
||||||
|
|
||||||
type CharacterSaveData struct {
|
type CharacterSaveData struct {
|
||||||
CharID uint32
|
CharID uint32
|
||||||
Name string
|
Name string
|
||||||
RP uint16
|
|
||||||
IsNewCharacter bool
|
IsNewCharacter bool
|
||||||
|
|
||||||
// Use provided setter/getter
|
Gender bool
|
||||||
baseSaveData []byte
|
RP uint16
|
||||||
|
HouseTier []byte
|
||||||
|
HouseData []byte
|
||||||
|
BookshelfData []byte
|
||||||
|
GalleryData []byte
|
||||||
|
ToreData []byte
|
||||||
|
GardenData []byte
|
||||||
|
WeaponType uint8
|
||||||
|
WeaponID uint16
|
||||||
|
HRP uint16
|
||||||
|
GR uint16
|
||||||
|
KQF []byte
|
||||||
|
|
||||||
|
compSave []byte
|
||||||
|
decompSave []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetCharacterSaveData(s *Session, charID uint32) (*CharacterSaveData, error) {
|
func GetCharacterSaveData(s *Session, charID uint32) (*CharacterSaveData, error) {
|
||||||
result, err := s.server.db.Query("SELECT id, savedata, is_new_character, name FROM characters WHERE id = $1", charID)
|
result, err := s.server.db.Query("SELECT id, savedata, is_new_character, name FROM characters WHERE id = $1", charID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error("failed to retrieve save data for character", zap.Error(err), zap.Uint32("charID", charID))
|
s.logger.Error("Failed to get savedata", zap.Error(err), zap.Uint32("charID", charID))
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer result.Close()
|
defer result.Close()
|
||||||
|
if !result.Next() {
|
||||||
|
s.logger.Error("No savedata found", zap.Uint32("charID", charID))
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
saveData := &CharacterSaveData{}
|
saveData := &CharacterSaveData{}
|
||||||
var compressedBaseSave []byte
|
err = result.Scan(&saveData.CharID, &saveData.compSave, &saveData.IsNewCharacter, &saveData.Name)
|
||||||
|
|
||||||
if !result.Next() {
|
|
||||||
s.logger.Error("no results found for character save data", zap.Uint32("charID", charID))
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = result.Scan(&saveData.CharID, &compressedBaseSave, &saveData.IsNewCharacter, &saveData.Name)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error(
|
s.logger.Error("Failed to scan savedata", zap.Error(err), zap.Uint32("charID", charID))
|
||||||
"failed to retrieve save data for character",
|
|
||||||
zap.Error(err),
|
|
||||||
zap.Uint32("charID", charID),
|
|
||||||
)
|
|
||||||
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if compressedBaseSave == nil {
|
if saveData.compSave == nil {
|
||||||
return saveData, nil
|
return saveData, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
decompressedBaseSave, err := nullcomp.Decompress(compressedBaseSave)
|
err = saveData.Decompress()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error("Failed to decompress savedata from db", zap.Error(err))
|
s.logger.Error("Failed to decompress savedata", zap.Error(err))
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
saveData.SetBaseSaveData(decompressedBaseSave)
|
saveData.updateStructWithSaveData()
|
||||||
|
|
||||||
return saveData, nil
|
return saveData, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (save *CharacterSaveData) Save(s *Session, transaction *sql.Tx) error {
|
func (save *CharacterSaveData) Save(s *Session) {
|
||||||
// We need to update the save data byte array before we save it back to the DB
|
if !s.kqfOverride {
|
||||||
|
s.kqf = save.KQF
|
||||||
|
} else {
|
||||||
|
save.KQF = s.kqf
|
||||||
|
}
|
||||||
|
|
||||||
save.updateSaveDataWithStruct()
|
save.updateSaveDataWithStruct()
|
||||||
|
|
||||||
compressedData, err := save.CompressedBaseData(s)
|
err := save.Compress()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
s.logger.Error("Failed to compress savedata", zap.Error(err))
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
updateSQL := "UPDATE characters SET savedata=$1, is_new_character=$3 WHERE id=$2"
|
_, err = s.server.db.Exec(`UPDATE characters SET savedata=$1, is_new_character=false, hrp=$2, gr=$3, is_female=$4, weapon_type=$5, weapon_id=$6 WHERE id=$7
|
||||||
|
`, save.compSave, save.HRP, save.GR, save.Gender, save.WeaponType, save.WeaponID, save.CharID)
|
||||||
if transaction != nil {
|
if err != nil {
|
||||||
_, err = transaction.Exec(updateSQL, compressedData, save.CharID, save.IsNewCharacter)
|
s.logger.Error("Failed to update savedata", zap.Error(err), zap.Uint32("charID", save.CharID))
|
||||||
} else {
|
}
|
||||||
_, err = s.server.db.Exec(updateSQL, compressedData, save.CharID, save.IsNewCharacter)
|
|
||||||
}
|
s.server.db.Exec(`UPDATE user_binary SET house_tier=$1, house_data=$2, bookshelf=$3, gallery=$4, tore=$5, garden=$6 WHERE id=$7
|
||||||
|
`, save.HouseTier, save.HouseData, save.BookshelfData, save.GalleryData, save.ToreData, save.GardenData, s.charID)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (save *CharacterSaveData) Compress() error {
|
||||||
|
var err error
|
||||||
|
save.compSave, err = nullcomp.Compress(save.decompSave)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error("failed to save character data", zap.Error(err), zap.Uint32("charID", save.CharID))
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (save *CharacterSaveData) CompressedBaseData(s *Session) ([]byte, error) {
|
func (save *CharacterSaveData) Decompress() error {
|
||||||
compressedData, err := nullcomp.Compress(save.baseSaveData)
|
var err error
|
||||||
|
save.decompSave, err = nullcomp.Decompress(save.compSave)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error("failed to compress saveData", zap.Error(err), zap.Uint32("charID", save.CharID))
|
return err
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
return compressedData, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (save *CharacterSaveData) BaseSaveData() []byte {
|
// This will update the character save with the values stored in the save struct
|
||||||
return save.baseSaveData
|
|
||||||
}
|
|
||||||
|
|
||||||
func (save *CharacterSaveData) SetBaseSaveData(data []byte) {
|
|
||||||
save.baseSaveData = data
|
|
||||||
// After setting the new save byte array, we can extract the values to update our struct
|
|
||||||
// This will be useful when we save it back, we use the struct values to overwrite the saveData
|
|
||||||
save.updateStructWithSaveData()
|
|
||||||
}
|
|
||||||
|
|
||||||
// This will update the save struct with the values stored in the raw savedata arrays
|
|
||||||
func (save *CharacterSaveData) updateSaveDataWithStruct() {
|
func (save *CharacterSaveData) updateSaveDataWithStruct() {
|
||||||
rpBytes := make([]byte, 2)
|
rpBytes := make([]byte, 2)
|
||||||
binary.LittleEndian.PutUint16(rpBytes, save.RP)
|
binary.LittleEndian.PutUint16(rpBytes, save.RP)
|
||||||
copy(save.baseSaveData[CharacterSaveRPPointer:CharacterSaveRPPointer+2], rpBytes)
|
copy(save.decompSave[pointerRP:pointerRP+2], rpBytes)
|
||||||
|
copy(save.decompSave[pointerKQF:pointerKQF+8], save.KQF)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This will update the character save struct with the values stored in the raw savedata arrays
|
// This will update the save struct with the values stored in the character save
|
||||||
func (save *CharacterSaveData) updateStructWithSaveData() {
|
func (save *CharacterSaveData) updateStructWithSaveData() {
|
||||||
save.RP = binary.LittleEndian.Uint16(save.baseSaveData[CharacterSaveRPPointer : CharacterSaveRPPointer+2])
|
if save.decompSave[pointerGender] == 1 {
|
||||||
|
save.Gender = true
|
||||||
|
} else {
|
||||||
|
save.Gender = false
|
||||||
|
}
|
||||||
|
if !save.IsNewCharacter {
|
||||||
|
save.RP = binary.LittleEndian.Uint16(save.decompSave[pointerRP : pointerRP+2])
|
||||||
|
save.HouseTier = save.decompSave[pointerHouseTier : pointerHouseTier+5]
|
||||||
|
save.HouseData = save.decompSave[pointerHouseData : pointerHouseData+195]
|
||||||
|
save.BookshelfData = save.decompSave[pointerBookshelfData : pointerBookshelfData+5576]
|
||||||
|
save.GalleryData = save.decompSave[pointerGalleryData : pointerGalleryData+1748]
|
||||||
|
save.ToreData = save.decompSave[pointerToreData : pointerToreData+240]
|
||||||
|
save.GardenData = save.decompSave[pointerGardenData : pointerGardenData+68]
|
||||||
|
save.WeaponType = save.decompSave[pointerWeaponType]
|
||||||
|
save.WeaponID = binary.LittleEndian.Uint16(save.decompSave[pointerWeaponID : pointerWeaponID+2])
|
||||||
|
save.HRP = binary.LittleEndian.Uint16(save.decompSave[pointerHRP : pointerHRP+2])
|
||||||
|
if save.HRP == uint16(999) {
|
||||||
|
save.GR = grpToGR(binary.LittleEndian.Uint32(save.decompSave[pointerGRP : pointerGRP+4]))
|
||||||
|
}
|
||||||
|
save.KQF = save.decompSave[pointerKQF : pointerKQF+8]
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfSexChanger(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfSexChanger(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package channelserver
|
package channelserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
"erupe-ce/common/bfutil"
|
||||||
"erupe-ce/common/stringsupport"
|
"erupe-ce/common/stringsupport"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -10,7 +10,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"erupe-ce/common/bfutil"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
"erupe-ce/network/mhfpacket"
|
"erupe-ce/network/mhfpacket"
|
||||||
"erupe-ce/server/channelserver/compression/deltacomp"
|
"erupe-ce/server/channelserver/compression/deltacomp"
|
||||||
@@ -26,7 +25,6 @@ func handleMsgMhfSavedata(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Var to hold the decompressed savedata for updating the launcher response fields.
|
// Var to hold the decompressed savedata for updating the launcher response fields.
|
||||||
var decompressedData []byte
|
|
||||||
if pkt.SaveType == 1 {
|
if pkt.SaveType == 1 {
|
||||||
// Diff-based update.
|
// Diff-based update.
|
||||||
// diffs themselves are also potentially compressed
|
// diffs themselves are also potentially compressed
|
||||||
@@ -36,77 +34,23 @@ func handleMsgMhfSavedata(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
// Perform diff.
|
// Perform diff.
|
||||||
s.logger.Info("Diffing...")
|
s.logger.Info("Diffing...")
|
||||||
characterSaveData.SetBaseSaveData(deltacomp.ApplyDataDiff(diff, characterSaveData.BaseSaveData()))
|
characterSaveData.decompSave = deltacomp.ApplyDataDiff(diff, characterSaveData.decompSave)
|
||||||
} else {
|
} else {
|
||||||
|
dumpSaveData(s, pkt.RawDataPayload, "savedata")
|
||||||
// Regular blob update.
|
// Regular blob update.
|
||||||
saveData, err := nullcomp.Decompress(pkt.RawDataPayload)
|
saveData, err := nullcomp.Decompress(pkt.RawDataPayload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Fatal("Failed to decompress savedata from packet", zap.Error(err))
|
s.logger.Fatal("Failed to decompress savedata from packet", zap.Error(err))
|
||||||
}
|
}
|
||||||
s.logger.Info("Updating save with blob")
|
s.logger.Info("Updating save with blob")
|
||||||
characterSaveData.SetBaseSaveData(saveData)
|
characterSaveData.decompSave = saveData
|
||||||
}
|
|
||||||
characterSaveData.IsNewCharacter = false
|
|
||||||
characterBaseSaveData := characterSaveData.BaseSaveData()
|
|
||||||
// Make a copy for updating the launcher fields.
|
|
||||||
decompressedData = make([]byte, len(characterBaseSaveData))
|
|
||||||
copy(decompressedData, characterBaseSaveData)
|
|
||||||
err = characterSaveData.Save(s, nil)
|
|
||||||
if err != nil {
|
|
||||||
s.logger.Fatal("Failed to update savedata in db", zap.Error(err))
|
|
||||||
}
|
}
|
||||||
|
characterSaveData.updateStructWithSaveData()
|
||||||
|
characterSaveData.Save(s)
|
||||||
s.logger.Info("Wrote recompressed savedata back to DB.")
|
s.logger.Info("Wrote recompressed savedata back to DB.")
|
||||||
dumpSaveData(s, pkt.RawDataPayload, "savedata")
|
|
||||||
|
|
||||||
_, err = s.server.db.Exec("UPDATE characters SET weapon_type=$1 WHERE id=$2", uint16(decompressedData[128789]), s.charID)
|
characterSaveData.Name = stringsupport.SJISToUTF8(bfutil.UpToNull(characterSaveData.decompSave[88:100]))
|
||||||
if err != nil {
|
_, err = s.server.db.Exec("UPDATE characters SET name=$1 WHERE id=$2", characterSaveData.Name, s.charID)
|
||||||
s.logger.Fatal("Failed to character weapon type in db", zap.Error(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
s.myseries.houseTier = decompressedData[129900:129905] // 0x1FB6C + 5
|
|
||||||
s.myseries.houseData = decompressedData[130561:130756] // 0x1FE01 + 195
|
|
||||||
s.myseries.bookshelfData = decompressedData[139928:145504] // 0x22298 + 5576
|
|
||||||
// Gallery data also exists at 0x21578, is this the contest submission?
|
|
||||||
s.myseries.galleryData = decompressedData[140064:141812] // 0x22320 + 1748
|
|
||||||
s.myseries.toreData = decompressedData[130228:130468] // 0x1FCB4 + 240
|
|
||||||
s.myseries.gardenData = decompressedData[142424:142492] // 0x22C58 + 68
|
|
||||||
|
|
||||||
isFemale := decompressedData[81] // 0x51
|
|
||||||
if isFemale == 1 {
|
|
||||||
_, err = s.server.db.Exec("UPDATE characters SET is_female=true WHERE id=$1", s.charID)
|
|
||||||
} else {
|
|
||||||
_, err = s.server.db.Exec("UPDATE characters SET is_female=false WHERE id=$1", s.charID)
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
s.logger.Fatal("Failed to character gender in db", zap.Error(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
weaponId := binary.LittleEndian.Uint16(decompressedData[128522:128524]) // 0x1F60A
|
|
||||||
_, err = s.server.db.Exec("UPDATE characters SET weapon_id=$1 WHERE id=$2", weaponId, s.charID)
|
|
||||||
if err != nil {
|
|
||||||
s.logger.Fatal("Failed to update character weapon id in db", zap.Error(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
hrp := binary.LittleEndian.Uint16(decompressedData[130550:130552]) // 0x1FDF6
|
|
||||||
_, err = s.server.db.Exec("UPDATE characters SET hrp=$1 WHERE id=$2", hrp, s.charID)
|
|
||||||
if err != nil {
|
|
||||||
s.logger.Fatal("Failed to update character hrp in db", zap.Error(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
grp := binary.LittleEndian.Uint32(decompressedData[130556:130560]) // 0x1FDFC
|
|
||||||
var gr uint16
|
|
||||||
if grp > 0 {
|
|
||||||
gr = grpToGR(grp)
|
|
||||||
} else {
|
|
||||||
gr = 0
|
|
||||||
}
|
|
||||||
_, err = s.server.db.Exec("UPDATE characters SET gr=$1 WHERE id=$2", gr, s.charID)
|
|
||||||
if err != nil {
|
|
||||||
s.logger.Fatal("Failed to update character gr in db", zap.Error(err))
|
|
||||||
}
|
|
||||||
|
|
||||||
characterName := s.clientContext.StrConv.MustDecode(bfutil.UpToNull(decompressedData[88:100]))
|
|
||||||
_, err = s.server.db.Exec("UPDATE characters SET name=$1 WHERE id=$2", characterName, s.charID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Fatal("Failed to update character name in db", zap.Error(err))
|
s.logger.Fatal("Failed to update character name in db", zap.Error(err))
|
||||||
}
|
}
|
||||||
@@ -275,15 +219,24 @@ func dumpSaveData(s *Session, data []byte, suffix string) {
|
|||||||
if !s.server.erupeConfig.DevModeOptions.SaveDumps.Enabled {
|
if !s.server.erupeConfig.DevModeOptions.SaveDumps.Enabled {
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
dir := filepath.Join(s.server.erupeConfig.DevModeOptions.SaveDumps.OutputDir, fmt.Sprintf("%d_%s", s.charID, s.Name))
|
dir := filepath.Join(s.server.erupeConfig.DevModeOptions.SaveDumps.OutputDir, fmt.Sprintf("%d", s.charID))
|
||||||
path := filepath.Join(s.server.erupeConfig.DevModeOptions.SaveDumps.OutputDir, fmt.Sprintf("%d_%s", s.charID, s.Name), fmt.Sprintf("%d_%s_%s.bin", s.charID, s.Name, suffix))
|
path := filepath.Join(s.server.erupeConfig.DevModeOptions.SaveDumps.OutputDir, fmt.Sprintf("%d", s.charID), fmt.Sprintf("%d_%s.bin", s.charID, suffix))
|
||||||
|
_, err := os.Stat(dir)
|
||||||
if _, err := os.Stat(dir); os.IsNotExist(err) {
|
|
||||||
os.Mkdir(dir, os.ModeDir)
|
|
||||||
}
|
|
||||||
err := ioutil.WriteFile(path, data, 0644)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Fatal("Error dumping savedata", zap.Error(err))
|
if os.IsNotExist(err) {
|
||||||
|
err = os.Mkdir(dir, os.ModeDir)
|
||||||
|
if err != nil {
|
||||||
|
s.logger.Warn("Error dumping savedata, could not create folder")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
s.logger.Warn("Error dumping savedata")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
err = os.WriteFile(path, data, 0644)
|
||||||
|
if err != nil {
|
||||||
|
s.logger.Warn("Error dumping savedata, could not write file", zap.Error(err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -320,7 +273,8 @@ func handleMsgMhfLoaddata(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
|
|
||||||
func handleMsgMhfSaveScenarioData(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfSaveScenarioData(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfSaveScenarioData)
|
pkt := p.(*mhfpacket.MsgMhfSaveScenarioData)
|
||||||
_, err := s.server.db.Exec("UPDATE characters SET scenariodata = $1 WHERE characters.id = $2", pkt.RawDataPayload, int(s.charID))
|
dumpSaveData(s, pkt.RawDataPayload, "scenario")
|
||||||
|
_, err := s.server.db.Exec("UPDATE characters SET scenariodata = $1 WHERE id = $2", pkt.RawDataPayload, s.charID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Fatal("Failed to update scenario data in db", zap.Error(err))
|
s.logger.Fatal("Failed to update scenario data in db", zap.Error(err))
|
||||||
}
|
}
|
||||||
@@ -337,7 +291,7 @@ func handleMsgMhfLoadScenarioData(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
pkt := p.(*mhfpacket.MsgMhfLoadScenarioData)
|
pkt := p.(*mhfpacket.MsgMhfLoadScenarioData)
|
||||||
var scenarioData []byte
|
var scenarioData []byte
|
||||||
bf := byteframe.NewByteFrame()
|
bf := byteframe.NewByteFrame()
|
||||||
err := s.server.db.QueryRow("SELECT scenariodata FROM characters WHERE characters.id = $1", int(s.charID)).Scan(&scenarioData)
|
err := s.server.db.QueryRow("SELECT scenariodata FROM characters WHERE id = $1", s.charID).Scan(&scenarioData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Fatal("Failed to get scenario data contents in db", zap.Error(err))
|
s.logger.Fatal("Failed to get scenario data contents in db", zap.Error(err))
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -53,38 +53,46 @@ func handleMsgMhfEnumerateEvent(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type activeFeature struct {
|
type activeFeature struct {
|
||||||
StartTime time.Time
|
StartTime time.Time `db:"start_time"`
|
||||||
ActiveFeatures uint32
|
ActiveFeatures uint32 `db:"featured"`
|
||||||
Unk1 uint16
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfGetWeeklySchedule(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfGetWeeklySchedule(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfGetWeeklySchedule)
|
pkt := p.(*mhfpacket.MsgMhfGetWeeklySchedule)
|
||||||
persistentEventSchedule := make([]activeFeature, 8) // generate day after weekly restart
|
|
||||||
for x := -1; x < 7; x++ {
|
var features []activeFeature
|
||||||
feat := generateActiveWeapons(14) // number of active weapons
|
rows, _ := s.server.db.Queryx(`SELECT start_time, featured FROM feature_weapon WHERE start_time=$1 OR start_time=$2`, Time_Current_Midnight().Add(-24*time.Hour), Time_Current_Midnight())
|
||||||
// TODO: only generate this once per restart (server should be restarted weekly)
|
for rows.Next() {
|
||||||
// then load data from db instead of regenerating
|
var feature activeFeature
|
||||||
persistentEventSchedule[x+1] = activeFeature{
|
rows.StructScan(&feature)
|
||||||
StartTime: Time_Current_Midnight().Add(time.Duration(24*x) * time.Hour),
|
features = append(features, feature)
|
||||||
ActiveFeatures: uint32(feat),
|
|
||||||
Unk1: 0,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := byteframe.NewByteFrame()
|
if len(features) < 2 {
|
||||||
resp.WriteUint8(uint8(len(persistentEventSchedule))) // Entry count, client only parses the first 7 or 8.
|
if len(features) == 0 {
|
||||||
resp.WriteUint32(uint32(Time_Current_Adjusted().Add(-5 * time.Minute).Unix())) // 5 minutes ago server time
|
feature := generateFeatureWeapons(s.server.erupeConfig.FeaturedWeapons)
|
||||||
|
feature.StartTime = Time_Current_Midnight().Add(-24 * time.Hour)
|
||||||
for _, es := range persistentEventSchedule {
|
features = append(features, feature)
|
||||||
resp.WriteUint32(uint32(es.StartTime.Unix()))
|
s.server.db.Exec(`INSERT INTO feature_weapon VALUES ($1, $2)`, feature.StartTime, feature.ActiveFeatures)
|
||||||
resp.WriteUint32(es.ActiveFeatures)
|
|
||||||
resp.WriteUint16(es.Unk1)
|
|
||||||
}
|
}
|
||||||
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
feature := generateFeatureWeapons(s.server.erupeConfig.FeaturedWeapons)
|
||||||
|
feature.StartTime = Time_Current_Midnight()
|
||||||
|
features = append(features, feature)
|
||||||
|
s.server.db.Exec(`INSERT INTO feature_weapon VALUES ($1, $2)`, feature.StartTime, feature.ActiveFeatures)
|
||||||
|
}
|
||||||
|
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteUint8(2)
|
||||||
|
bf.WriteUint32(uint32(Time_Current_Adjusted().Add(-5 * time.Minute).Unix()))
|
||||||
|
for _, feature := range features {
|
||||||
|
bf.WriteUint32(uint32(feature.StartTime.Unix()))
|
||||||
|
bf.WriteUint32(feature.ActiveFeatures)
|
||||||
|
bf.WriteUint16(0)
|
||||||
|
}
|
||||||
|
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateActiveWeapons(count int) int {
|
func generateFeatureWeapons(count int) activeFeature {
|
||||||
nums := make([]int, 0)
|
nums := make([]int, 0)
|
||||||
var result int
|
var result int
|
||||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
@@ -104,7 +112,7 @@ func generateActiveWeapons(count int) int {
|
|||||||
for _, num := range nums {
|
for _, num := range nums {
|
||||||
result += int(math.Pow(2, float64(num)))
|
result += int(math.Pow(2, float64(num)))
|
||||||
}
|
}
|
||||||
return result
|
return activeFeature{ActiveFeatures: uint32(result)}
|
||||||
}
|
}
|
||||||
|
|
||||||
type loginBoost struct {
|
type loginBoost struct {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
ps "erupe-ce/common/pascalstring"
|
ps "erupe-ce/common/pascalstring"
|
||||||
"erupe-ce/network/mhfpacket"
|
"erupe-ce/network/mhfpacket"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -253,11 +254,19 @@ func handleMsgMhfStateFestaU(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var souls uint32
|
var souls, exists uint32
|
||||||
s.server.db.QueryRow("SELECT souls FROM guild_characters WHERE character_id=$1", s.charID).Scan(&souls)
|
s.server.db.QueryRow("SELECT souls FROM guild_characters WHERE character_id=$1", s.charID).Scan(&souls)
|
||||||
|
err = s.server.db.QueryRow("SELECT prize_id FROM festa_prizes_accepted WHERE prize_id=0 AND character_id=$1", s.charID).Scan(&exists)
|
||||||
bf := byteframe.NewByteFrame()
|
bf := byteframe.NewByteFrame()
|
||||||
bf.WriteUint32(souls)
|
bf.WriteUint32(souls)
|
||||||
bf.WriteUint32(0) // unk
|
if err != nil {
|
||||||
|
bf.WriteBool(true)
|
||||||
|
bf.WriteBool(false)
|
||||||
|
} else {
|
||||||
|
bf.WriteBool(false)
|
||||||
|
bf.WriteBool(true)
|
||||||
|
}
|
||||||
|
bf.WriteUint16(0) // Unk
|
||||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,10 +289,10 @@ func handleMsgMhfStateFestaG(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
resp.WriteUint32(guild.Souls)
|
resp.WriteUint32(guild.Souls)
|
||||||
resp.WriteUint32(0) // unk
|
resp.WriteUint32(1) // unk
|
||||||
resp.WriteUint32(0) // unk, rank?
|
resp.WriteUint32(1) // unk
|
||||||
resp.WriteUint32(0) // unk
|
resp.WriteUint32(1) // unk, rank?
|
||||||
resp.WriteUint32(0) // unk
|
resp.WriteUint32(1) // unk
|
||||||
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -302,6 +311,9 @@ func handleMsgMhfEnumerateFestaMember(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
bf := byteframe.NewByteFrame()
|
bf := byteframe.NewByteFrame()
|
||||||
bf.WriteUint16(uint16(len(members)))
|
bf.WriteUint16(uint16(len(members)))
|
||||||
bf.WriteUint16(0) // Unk
|
bf.WriteUint16(0) // Unk
|
||||||
|
sort.Slice(members, func(i, j int) bool {
|
||||||
|
return members[i].Souls > members[j].Souls
|
||||||
|
})
|
||||||
for _, member := range members {
|
for _, member := range members {
|
||||||
bf.WriteUint32(member.CharID)
|
bf.WriteUint32(member.CharID)
|
||||||
bf.WriteUint32(member.Souls)
|
bf.WriteUint32(member.Souls)
|
||||||
@@ -342,6 +354,7 @@ func handleMsgMhfChargeFesta(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
|
|
||||||
func handleMsgMhfAcquireFesta(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfAcquireFesta(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfAcquireFesta)
|
pkt := p.(*mhfpacket.MsgMhfAcquireFesta)
|
||||||
|
s.server.db.Exec("INSERT INTO public.festa_prizes_accepted VALUES (0, $1)", s.charID)
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -368,7 +381,7 @@ type Prize struct {
|
|||||||
|
|
||||||
func handleMsgMhfEnumerateFestaPersonalPrize(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfEnumerateFestaPersonalPrize(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfEnumerateFestaPersonalPrize)
|
pkt := p.(*mhfpacket.MsgMhfEnumerateFestaPersonalPrize)
|
||||||
rows, _ := s.server.db.Queryx("SELECT id, tier, souls_req, item_id, num_item, (SELECT count(*) FROM festa_prizes_accepted fpa WHERE fp.id = fpa.prize_id AND fpa.character_id = 4) AS claimed FROM festa_prizes fp WHERE type='personal'")
|
rows, _ := s.server.db.Queryx(`SELECT id, tier, souls_req, item_id, num_item, (SELECT count(*) FROM festa_prizes_accepted fpa WHERE fp.id = fpa.prize_id AND fpa.character_id = $1) AS claimed FROM festa_prizes fp WHERE type='personal'`, s.charID)
|
||||||
var count uint32
|
var count uint32
|
||||||
prizeData := byteframe.NewByteFrame()
|
prizeData := byteframe.NewByteFrame()
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
@@ -394,7 +407,7 @@ func handleMsgMhfEnumerateFestaPersonalPrize(s *Session, p mhfpacket.MHFPacket)
|
|||||||
|
|
||||||
func handleMsgMhfEnumerateFestaIntermediatePrize(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfEnumerateFestaIntermediatePrize(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfEnumerateFestaIntermediatePrize)
|
pkt := p.(*mhfpacket.MsgMhfEnumerateFestaIntermediatePrize)
|
||||||
rows, _ := s.server.db.Queryx("SELECT id, tier, souls_req, item_id, num_item, (SELECT count(*) FROM festa_prizes_accepted fpa WHERE fp.id = fpa.prize_id AND fpa.character_id = 4) AS claimed FROM festa_prizes fp WHERE type='guild'")
|
rows, _ := s.server.db.Queryx(`SELECT id, tier, souls_req, item_id, num_item, (SELECT count(*) FROM festa_prizes_accepted fpa WHERE fp.id = fpa.prize_id AND fpa.character_id = $1) AS claimed FROM festa_prizes fp WHERE type='guild'`, s.charID)
|
||||||
var count uint32
|
var count uint32
|
||||||
prizeData := byteframe.NewByteFrame()
|
prizeData := byteframe.NewByteFrame()
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -54,6 +55,10 @@ type Guild struct {
|
|||||||
PugiName1 string `db:"pugi_name_1"`
|
PugiName1 string `db:"pugi_name_1"`
|
||||||
PugiName2 string `db:"pugi_name_2"`
|
PugiName2 string `db:"pugi_name_2"`
|
||||||
PugiName3 string `db:"pugi_name_3"`
|
PugiName3 string `db:"pugi_name_3"`
|
||||||
|
PugiOutfit1 uint8 `db:"pugi_outfit_1"`
|
||||||
|
PugiOutfit2 uint8 `db:"pugi_outfit_2"`
|
||||||
|
PugiOutfit3 uint8 `db:"pugi_outfit_3"`
|
||||||
|
PugiOutfits uint32 `db:"pugi_outfits"`
|
||||||
Recruiting bool `db:"recruiting"`
|
Recruiting bool `db:"recruiting"`
|
||||||
FestivalColour FestivalColour `db:"festival_colour"`
|
FestivalColour FestivalColour `db:"festival_colour"`
|
||||||
Souls uint32 `db:"souls"`
|
Souls uint32 `db:"souls"`
|
||||||
@@ -125,6 +130,10 @@ SELECT
|
|||||||
COALESCE(pugi_name_1, '') AS pugi_name_1,
|
COALESCE(pugi_name_1, '') AS pugi_name_1,
|
||||||
COALESCE(pugi_name_2, '') AS pugi_name_2,
|
COALESCE(pugi_name_2, '') AS pugi_name_2,
|
||||||
COALESCE(pugi_name_3, '') AS pugi_name_3,
|
COALESCE(pugi_name_3, '') AS pugi_name_3,
|
||||||
|
pugi_outfit_1,
|
||||||
|
pugi_outfit_2,
|
||||||
|
pugi_outfit_3,
|
||||||
|
pugi_outfits,
|
||||||
recruiting,
|
recruiting,
|
||||||
COALESCE((SELECT team FROM festa_registrations fr WHERE fr.guild_id = g.id), 'none') AS festival_colour,
|
COALESCE((SELECT team FROM festa_registrations fr WHERE fr.guild_id = g.id), 'none') AS festival_colour,
|
||||||
(SELECT SUM(souls) FROM guild_characters gc WHERE gc.guild_id = g.id) AS souls,
|
(SELECT SUM(souls) FROM guild_characters gc WHERE gc.guild_id = g.id) AS souls,
|
||||||
@@ -151,8 +160,10 @@ SELECT
|
|||||||
|
|
||||||
func (guild *Guild) Save(s *Session) error {
|
func (guild *Guild) Save(s *Session) error {
|
||||||
_, err := s.server.db.Exec(`
|
_, err := s.server.db.Exec(`
|
||||||
UPDATE guilds SET main_motto=$2, sub_motto=$3, comment=$4, pugi_name_1=$5, pugi_name_2=$6, pugi_name_3=$7, icon=$8, leader_id=$9 WHERE id=$1
|
UPDATE guilds SET main_motto=$2, sub_motto=$3, comment=$4, pugi_name_1=$5, pugi_name_2=$6, pugi_name_3=$7,
|
||||||
`, guild.ID, guild.MainMotto, guild.SubMotto, guild.Comment, guild.PugiName1, guild.PugiName2, guild.PugiName3, guild.Icon, guild.GuildLeader.LeaderCharID)
|
pugi_outfit_1=$8, pugi_outfit_2=$9, pugi_outfit_3=$10, pugi_outfits=$11, icon=$12, leader_id=$13 WHERE id=$1
|
||||||
|
`, guild.ID, guild.MainMotto, guild.SubMotto, guild.Comment, guild.PugiName1, guild.PugiName2, guild.PugiName3,
|
||||||
|
guild.PugiOutfit1, guild.PugiOutfit2, guild.PugiOutfit3, guild.PugiOutfits, guild.Icon, guild.GuildLeader.LeaderCharID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error("failed to update guild data", zap.Error(err), zap.Uint32("guildID", guild.ID))
|
s.logger.Error("failed to update guild data", zap.Error(err), zap.Uint32("guildID", guild.ID))
|
||||||
@@ -164,7 +175,7 @@ func (guild *Guild) Save(s *Session) error {
|
|||||||
|
|
||||||
func (guild *Guild) CreateApplication(s *Session, charID uint32, applicationType GuildApplicationType, transaction *sql.Tx) error {
|
func (guild *Guild) CreateApplication(s *Session, charID uint32, applicationType GuildApplicationType, transaction *sql.Tx) error {
|
||||||
|
|
||||||
sql := `
|
query := `
|
||||||
INSERT INTO guild_applications (guild_id, character_id, actor_id, application_type)
|
INSERT INTO guild_applications (guild_id, character_id, actor_id, application_type)
|
||||||
VALUES ($1, $2, $3, $4)
|
VALUES ($1, $2, $3, $4)
|
||||||
`
|
`
|
||||||
@@ -172,9 +183,9 @@ func (guild *Guild) CreateApplication(s *Session, charID uint32, applicationType
|
|||||||
var err error
|
var err error
|
||||||
|
|
||||||
if transaction == nil {
|
if transaction == nil {
|
||||||
_, err = s.server.db.Exec(sql, guild.ID, charID, s.charID, applicationType)
|
_, err = s.server.db.Exec(query, guild.ID, charID, s.charID, applicationType)
|
||||||
} else {
|
} else {
|
||||||
_, err = transaction.Exec(sql, guild.ID, charID, s.charID, applicationType)
|
_, err = transaction.Exec(query, guild.ID, charID, s.charID, applicationType)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -222,7 +233,7 @@ func (guild *Guild) Disband(s *Session) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = transaction.Exec("UPDATE guild_alliances SET sub1_id=NULL WHERE sub1_id=$1", guild.ID)
|
_, err = transaction.Exec("UPDATE guild_alliances SET sub1_id=sub2_id, sub2_id=NULL WHERE sub1_id=$1", guild.ID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error("failed to remove guild from alliance", zap.Error(err), zap.Uint32("guildID", guild.ID))
|
s.logger.Error("failed to remove guild from alliance", zap.Error(err), zap.Uint32("guildID", guild.ID))
|
||||||
@@ -634,11 +645,8 @@ func handleMsgMhfOperateGuild(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bf.WriteUint32(uint32(response))
|
bf.WriteUint32(uint32(response))
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
|
|
||||||
return
|
|
||||||
case mhfpacket.OPERATE_GUILD_RESIGN:
|
case mhfpacket.OPERATE_GUILD_RESIGN:
|
||||||
guildMembers, err := GetGuildMembers(s, guild.ID, false)
|
guildMembers, err := GetGuildMembers(s, guild.ID, false)
|
||||||
success := false
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
sort.Slice(guildMembers[:], func(i, j int) bool {
|
sort.Slice(guildMembers[:], func(i, j int) bool {
|
||||||
return guildMembers[i].OrderIndex < guildMembers[j].OrderIndex
|
return guildMembers[i].OrderIndex < guildMembers[j].OrderIndex
|
||||||
@@ -651,29 +659,17 @@ func handleMsgMhfOperateGuild(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
guildMembers[0].Save(s)
|
guildMembers[0].Save(s)
|
||||||
guildMembers[i].Save(s)
|
guildMembers[i].Save(s)
|
||||||
bf.WriteUint32(guildMembers[i].CharID)
|
bf.WriteUint32(guildMembers[i].CharID)
|
||||||
success = true
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
guild.Save(s)
|
guild.Save(s)
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
|
|
||||||
}
|
}
|
||||||
if !success {
|
|
||||||
bf.WriteUint32(0)
|
|
||||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
|
||||||
}
|
|
||||||
return
|
|
||||||
case mhfpacket.OPERATE_GUILD_APPLY:
|
case mhfpacket.OPERATE_GUILD_APPLY:
|
||||||
err = guild.CreateApplication(s, s.charID, GuildApplicationTypeApplied, nil)
|
err = guild.CreateApplication(s, s.charID, GuildApplicationTypeApplied, nil)
|
||||||
|
|
||||||
if err != nil {
|
if err == nil {
|
||||||
// All successful acks return 0x01, assuming 0x00 is failure
|
|
||||||
bf.WriteUint32(0x00)
|
|
||||||
} else {
|
|
||||||
bf.WriteUint32(guild.LeaderCharID)
|
bf.WriteUint32(guild.LeaderCharID)
|
||||||
}
|
}
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
|
|
||||||
return
|
|
||||||
case mhfpacket.OPERATE_GUILD_LEAVE:
|
case mhfpacket.OPERATE_GUILD_LEAVE:
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@@ -698,10 +694,8 @@ func handleMsgMhfOperateGuild(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bf.WriteUint32(uint32(response))
|
bf.WriteUint32(uint32(response))
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
|
|
||||||
return
|
|
||||||
case mhfpacket.OPERATE_GUILD_DONATE_RANK:
|
case mhfpacket.OPERATE_GUILD_DONATE_RANK:
|
||||||
handleDonateRP(s, pkt, bf, guild, false)
|
bf.WriteBytes(handleDonateRP(s, uint16(pkt.Data1.ReadUint32()), guild, false))
|
||||||
case mhfpacket.OPERATE_GUILD_SET_APPLICATION_DENY:
|
case mhfpacket.OPERATE_GUILD_SET_APPLICATION_DENY:
|
||||||
s.server.db.Exec("UPDATE guilds SET recruiting=false WHERE id=$1", guild.ID)
|
s.server.db.Exec("UPDATE guilds SET recruiting=false WHERE id=$1", guild.ID)
|
||||||
case mhfpacket.OPERATE_GUILD_SET_APPLICATION_ALLOW:
|
case mhfpacket.OPERATE_GUILD_SET_APPLICATION_ALLOW:
|
||||||
@@ -711,46 +705,55 @@ func handleMsgMhfOperateGuild(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
case mhfpacket.OPERATE_GUILD_SET_AVOID_LEADERSHIP_FALSE:
|
case mhfpacket.OPERATE_GUILD_SET_AVOID_LEADERSHIP_FALSE:
|
||||||
handleAvoidLeadershipUpdate(s, pkt, false)
|
handleAvoidLeadershipUpdate(s, pkt, false)
|
||||||
case mhfpacket.OPERATE_GUILD_UPDATE_COMMENT:
|
case mhfpacket.OPERATE_GUILD_UPDATE_COMMENT:
|
||||||
pbf := byteframe.NewByteFrameFromBytes(pkt.UnkData)
|
|
||||||
if !characterGuildInfo.IsLeader && !characterGuildInfo.IsSubLeader() {
|
if !characterGuildInfo.IsLeader && !characterGuildInfo.IsSubLeader() {
|
||||||
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_ = pbf.ReadUint8() // len
|
guild.Comment = stringsupport.SJISToUTF8(pkt.Data2.ReadNullTerminatedBytes())
|
||||||
_ = pbf.ReadUint32()
|
|
||||||
guild.Comment = stringsupport.SJISToUTF8(pbf.ReadNullTerminatedBytes())
|
|
||||||
guild.Save(s)
|
guild.Save(s)
|
||||||
case mhfpacket.OPERATE_GUILD_UPDATE_MOTTO:
|
case mhfpacket.OPERATE_GUILD_UPDATE_MOTTO:
|
||||||
if !characterGuildInfo.IsLeader && !characterGuildInfo.IsSubLeader() {
|
if !characterGuildInfo.IsLeader && !characterGuildInfo.IsSubLeader() {
|
||||||
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
guild.SubMotto = pkt.UnkData[3]
|
_ = pkt.Data1.ReadUint16()
|
||||||
guild.MainMotto = pkt.UnkData[4]
|
guild.SubMotto = pkt.Data1.ReadUint8()
|
||||||
|
guild.MainMotto = pkt.Data1.ReadUint8()
|
||||||
guild.Save(s)
|
guild.Save(s)
|
||||||
case mhfpacket.OPERATE_GUILD_RENAME_PUGI_1:
|
case mhfpacket.OPERATE_GUILD_RENAME_PUGI_1:
|
||||||
handleRenamePugi(s, pkt.UnkData, guild, 1)
|
handleRenamePugi(s, pkt.Data2, guild, 1)
|
||||||
case mhfpacket.OPERATE_GUILD_RENAME_PUGI_2:
|
case mhfpacket.OPERATE_GUILD_RENAME_PUGI_2:
|
||||||
handleRenamePugi(s, pkt.UnkData, guild, 2)
|
handleRenamePugi(s, pkt.Data2, guild, 2)
|
||||||
case mhfpacket.OPERATE_GUILD_RENAME_PUGI_3:
|
case mhfpacket.OPERATE_GUILD_RENAME_PUGI_3:
|
||||||
handleRenamePugi(s, pkt.UnkData, guild, 3)
|
handleRenamePugi(s, pkt.Data2, guild, 3)
|
||||||
case mhfpacket.OPERATE_GUILD_CHANGE_PUGI_1:
|
case mhfpacket.OPERATE_GUILD_CHANGE_PUGI_1:
|
||||||
// TODO: decode guild poogie outfits
|
handleChangePugi(s, uint8(pkt.Data1.ReadUint32()), guild, 1)
|
||||||
case mhfpacket.OPERATE_GUILD_CHANGE_PUGI_2:
|
case mhfpacket.OPERATE_GUILD_CHANGE_PUGI_2:
|
||||||
|
handleChangePugi(s, uint8(pkt.Data1.ReadUint32()), guild, 2)
|
||||||
case mhfpacket.OPERATE_GUILD_CHANGE_PUGI_3:
|
case mhfpacket.OPERATE_GUILD_CHANGE_PUGI_3:
|
||||||
|
handleChangePugi(s, uint8(pkt.Data1.ReadUint32()), guild, 3)
|
||||||
|
case mhfpacket.OPERATE_GUILD_UNLOCK_OUTFIT:
|
||||||
|
// TODO: This doesn't implement blocking, if someone unlocked the same outfit at the same time
|
||||||
|
s.server.db.Exec(`UPDATE guilds SET pugi_outfits=pugi_outfits+$1 WHERE id=$2`, int(math.Pow(float64(pkt.Data1.ReadUint32()), 2)), guild.ID)
|
||||||
case mhfpacket.OPERATE_GUILD_DONATE_EVENT:
|
case mhfpacket.OPERATE_GUILD_DONATE_EVENT:
|
||||||
handleDonateRP(s, pkt, bf, guild, true)
|
bf.WriteBytes(handleDonateRP(s, uint16(pkt.Data1.ReadUint32()), guild, true))
|
||||||
|
case mhfpacket.OPERATE_GUILD_EVENT_EXCHANGE:
|
||||||
|
rp := uint16(pkt.Data1.ReadUint32())
|
||||||
|
var balance uint32
|
||||||
|
s.server.db.QueryRow(`UPDATE guilds SET event_rp=event_rp-$1 WHERE id=$2 RETURNING event_rp`, rp, guild.ID).Scan(&balance)
|
||||||
|
bf.WriteUint32(balance)
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("unhandled operate guild action '%d'", pkt.Action))
|
panic(fmt.Sprintf("unhandled operate guild action '%d'", pkt.Action))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(bf.Data()) > 0 {
|
||||||
|
doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
|
||||||
|
} else {
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleRenamePugi(s *Session, data []byte, guild *Guild, num int) {
|
func handleRenamePugi(s *Session, bf *byteframe.ByteFrame, guild *Guild, num int) {
|
||||||
bf := byteframe.NewByteFrameFromBytes(data)
|
|
||||||
_ = bf.ReadUint8() // len
|
|
||||||
_ = bf.ReadUint32() // unk
|
|
||||||
name := stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes())
|
name := stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes())
|
||||||
switch num {
|
switch num {
|
||||||
case 1:
|
case 1:
|
||||||
@@ -763,33 +766,35 @@ func handleRenamePugi(s *Session, data []byte, guild *Guild, num int) {
|
|||||||
guild.Save(s)
|
guild.Save(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleDonateRP(s *Session, pkt *mhfpacket.MsgMhfOperateGuild, bf *byteframe.ByteFrame, guild *Guild, isEvent bool) error {
|
func handleChangePugi(s *Session, outfit uint8, guild *Guild, num int) {
|
||||||
rp := binary.BigEndian.Uint16(pkt.UnkData[3:5])
|
switch num {
|
||||||
|
case 1:
|
||||||
|
guild.PugiOutfit1 = outfit
|
||||||
|
case 2:
|
||||||
|
guild.PugiOutfit2 = outfit
|
||||||
|
case 3:
|
||||||
|
guild.PugiOutfit3 = outfit
|
||||||
|
}
|
||||||
|
guild.Save(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleDonateRP(s *Session, amount uint16, guild *Guild, isEvent bool) []byte {
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteUint32(0)
|
||||||
saveData, err := GetCharacterSaveData(s, s.charID)
|
saveData, err := GetCharacterSaveData(s, s.charID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return bf.Data()
|
||||||
}
|
|
||||||
saveData.RP -= rp
|
|
||||||
transaction, err := s.server.db.Begin()
|
|
||||||
err = saveData.Save(s, transaction)
|
|
||||||
if err != nil {
|
|
||||||
transaction.Rollback()
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
saveData.RP -= amount
|
||||||
|
saveData.Save(s)
|
||||||
updateSQL := "UPDATE guilds SET rank_rp = rank_rp + $1 WHERE id = $2"
|
updateSQL := "UPDATE guilds SET rank_rp = rank_rp + $1 WHERE id = $2"
|
||||||
if isEvent {
|
if isEvent {
|
||||||
updateSQL = "UPDATE guilds SET event_rp = event_rp + $1 WHERE id = $2"
|
updateSQL = "UPDATE guilds SET event_rp = event_rp + $1 WHERE id = $2"
|
||||||
}
|
}
|
||||||
_, err = s.server.db.Exec(updateSQL, rp, guild.ID)
|
s.server.db.Exec(updateSQL, amount, guild.ID)
|
||||||
if err != nil {
|
bf.Seek(0, 0)
|
||||||
s.logger.Error("Failed to donate rank RP to guild", zap.Error(err), zap.Uint32("guildID", guild.ID))
|
|
||||||
transaction.Rollback()
|
|
||||||
return err
|
|
||||||
} else {
|
|
||||||
transaction.Commit()
|
|
||||||
}
|
|
||||||
bf.WriteUint32(uint32(saveData.RP))
|
bf.WriteUint32(uint32(saveData.RP))
|
||||||
return nil
|
return bf.Data()
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleAvoidLeadershipUpdate(s *Session, pkt *mhfpacket.MsgMhfOperateGuild, avoidLeadership bool) {
|
func handleAvoidLeadershipUpdate(s *Session, pkt *mhfpacket.MsgMhfOperateGuild, avoidLeadership bool) {
|
||||||
@@ -952,11 +957,13 @@ func handleMsgMhfInfoGuild(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
ps.Uint8(bf, guild.PugiName1, true)
|
ps.Uint8(bf, guild.PugiName1, true)
|
||||||
ps.Uint8(bf, guild.PugiName2, true)
|
ps.Uint8(bf, guild.PugiName2, true)
|
||||||
ps.Uint8(bf, guild.PugiName3, true)
|
ps.Uint8(bf, guild.PugiName3, true)
|
||||||
|
bf.WriteUint8(guild.PugiOutfit1)
|
||||||
// probably guild pugi properties, should be status, stamina and luck outfits
|
bf.WriteUint8(guild.PugiOutfit2)
|
||||||
bf.WriteBytes([]byte{
|
bf.WriteUint8(guild.PugiOutfit3)
|
||||||
0x04, 0x02, 0x03, 0x04, 0x02, 0x03, 0x00, 0x00, 0x00, 0x4E,
|
bf.WriteUint8(guild.PugiOutfit1)
|
||||||
})
|
bf.WriteUint8(guild.PugiOutfit2)
|
||||||
|
bf.WriteUint8(guild.PugiOutfit3)
|
||||||
|
bf.WriteUint32(guild.PugiOutfits)
|
||||||
|
|
||||||
// Unk flags
|
// Unk flags
|
||||||
bf.WriteUint8(0x3C) // also seen as 0x32 on JP and 0x64 on TW
|
bf.WriteUint8(0x3C) // also seen as 0x32 on JP and 0x64 on TW
|
||||||
@@ -1027,15 +1034,7 @@ func handleMsgMhfInfoGuild(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
applicants, err := GetGuildMembers(s, guild.ID, true)
|
applicants, err := GetGuildMembers(s, guild.ID, true)
|
||||||
|
if err != nil || (characterGuildData != nil && !characterGuildData.CanRecruit()) {
|
||||||
if err != nil {
|
|
||||||
resp := byteframe.NewByteFrame()
|
|
||||||
resp.WriteUint32(0) // Count
|
|
||||||
resp.WriteUint8(0) // Unk, read if count == 0.
|
|
||||||
|
|
||||||
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
|
||||||
}
|
|
||||||
if err != nil || characterGuildData.IsApplicant {
|
|
||||||
bf.WriteUint16(0)
|
bf.WriteUint16(0)
|
||||||
} else {
|
} else {
|
||||||
bf.WriteUint16(uint16(len(applicants)))
|
bf.WriteUint16(uint16(len(applicants)))
|
||||||
@@ -1049,7 +1048,7 @@ func handleMsgMhfInfoGuild(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bf.WriteUint16(0x0000)
|
bf.WriteUint16(0x0000) // lenAllianceApplications
|
||||||
|
|
||||||
/*
|
/*
|
||||||
alliance application format
|
alliance application format
|
||||||
@@ -1095,15 +1094,16 @@ func handleMsgMhfEnumerateGuild(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
pkt := p.(*mhfpacket.MsgMhfEnumerateGuild)
|
pkt := p.(*mhfpacket.MsgMhfEnumerateGuild)
|
||||||
|
|
||||||
var guilds []*Guild
|
var guilds []*Guild
|
||||||
|
var alliances []*GuildAlliance
|
||||||
var rows *sqlx.Rows
|
var rows *sqlx.Rows
|
||||||
var err error
|
var err error
|
||||||
bf := byteframe.NewByteFrameFromBytes(pkt.RawDataPayload)
|
bf := byteframe.NewByteFrameFromBytes(pkt.RawDataPayload)
|
||||||
|
|
||||||
switch pkt.Type {
|
switch pkt.Type {
|
||||||
case mhfpacket.ENUMERATE_GUILD_TYPE_GUILD_NAME:
|
case mhfpacket.ENUMERATE_GUILD_TYPE_GUILD_NAME:
|
||||||
bf.ReadBytes(10)
|
bf.ReadBytes(8)
|
||||||
searchTerm := fmt.Sprintf(`%%%s%%`, stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes()))
|
searchTerm := fmt.Sprintf(`%%%s%%`, stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes()))
|
||||||
rows, err = s.server.db.Queryx(fmt.Sprintf(`%s WHERE g.name ILIKE $1 OFFSET $2`, guildInfoSelectQuery), searchTerm, pkt.Page*10)
|
rows, err = s.server.db.Queryx(fmt.Sprintf(`%s WHERE g.name ILIKE $1 OFFSET $2 LIMIT 11`, guildInfoSelectQuery), searchTerm, pkt.Page*10)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
guild, _ := buildGuildObjectFromDbResult(rows, err, s)
|
guild, _ := buildGuildObjectFromDbResult(rows, err, s)
|
||||||
@@ -1111,9 +1111,9 @@ func handleMsgMhfEnumerateGuild(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case mhfpacket.ENUMERATE_GUILD_TYPE_LEADER_NAME:
|
case mhfpacket.ENUMERATE_GUILD_TYPE_LEADER_NAME:
|
||||||
bf.ReadBytes(10)
|
bf.ReadBytes(8)
|
||||||
searchTerm := fmt.Sprintf(`%%%s%%`, stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes()))
|
searchTerm := fmt.Sprintf(`%%%s%%`, stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes()))
|
||||||
rows, err = s.server.db.Queryx(fmt.Sprintf(`%s WHERE lc.name ILIKE $1 OFFSET $2`, guildInfoSelectQuery), searchTerm, pkt.Page*10)
|
rows, err = s.server.db.Queryx(fmt.Sprintf(`%s WHERE lc.name ILIKE $1 OFFSET $2 LIMIT 11`, guildInfoSelectQuery), searchTerm, pkt.Page*10)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
guild, _ := buildGuildObjectFromDbResult(rows, err, s)
|
guild, _ := buildGuildObjectFromDbResult(rows, err, s)
|
||||||
@@ -1121,7 +1121,6 @@ func handleMsgMhfEnumerateGuild(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case mhfpacket.ENUMERATE_GUILD_TYPE_LEADER_ID:
|
case mhfpacket.ENUMERATE_GUILD_TYPE_LEADER_ID:
|
||||||
bf.ReadBytes(2)
|
|
||||||
ID := bf.ReadUint32()
|
ID := bf.ReadUint32()
|
||||||
rows, err = s.server.db.Queryx(fmt.Sprintf(`%s WHERE leader_id = $1`, guildInfoSelectQuery), ID)
|
rows, err = s.server.db.Queryx(fmt.Sprintf(`%s WHERE leader_id = $1`, guildInfoSelectQuery), ID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@@ -1131,11 +1130,10 @@ func handleMsgMhfEnumerateGuild(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case mhfpacket.ENUMERATE_GUILD_TYPE_ORDER_MEMBERS:
|
case mhfpacket.ENUMERATE_GUILD_TYPE_ORDER_MEMBERS:
|
||||||
sorting := bf.ReadUint8()
|
if pkt.Sorting {
|
||||||
if sorting == 1 {
|
rows, err = s.server.db.Queryx(fmt.Sprintf(`%s ORDER BY member_count DESC OFFSET $1 LIMIT 11`, guildInfoSelectQuery), pkt.Page*10)
|
||||||
rows, err = s.server.db.Queryx(fmt.Sprintf(`%s ORDER BY member_count DESC OFFSET $1`, guildInfoSelectQuery), pkt.Page*10)
|
|
||||||
} else {
|
} else {
|
||||||
rows, err = s.server.db.Queryx(fmt.Sprintf(`%s ORDER BY member_count ASC OFFSET $1`, guildInfoSelectQuery), pkt.Page*10)
|
rows, err = s.server.db.Queryx(fmt.Sprintf(`%s ORDER BY member_count ASC OFFSET $1 LIMIT 11`, guildInfoSelectQuery), pkt.Page*10)
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
@@ -1144,11 +1142,10 @@ func handleMsgMhfEnumerateGuild(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case mhfpacket.ENUMERATE_GUILD_TYPE_ORDER_REGISTRATION:
|
case mhfpacket.ENUMERATE_GUILD_TYPE_ORDER_REGISTRATION:
|
||||||
sorting := bf.ReadUint8()
|
if pkt.Sorting {
|
||||||
if sorting == 1 {
|
rows, err = s.server.db.Queryx(fmt.Sprintf(`%s ORDER BY id ASC OFFSET $1 LIMIT 11`, guildInfoSelectQuery), pkt.Page*10)
|
||||||
rows, err = s.server.db.Queryx(fmt.Sprintf(`%s ORDER BY id ASC OFFSET $1`, guildInfoSelectQuery), pkt.Page*10)
|
|
||||||
} else {
|
} else {
|
||||||
rows, err = s.server.db.Queryx(fmt.Sprintf(`%s ORDER BY id DESC OFFSET $1`, guildInfoSelectQuery), pkt.Page*10)
|
rows, err = s.server.db.Queryx(fmt.Sprintf(`%s ORDER BY id DESC OFFSET $1 LIMIT 11`, guildInfoSelectQuery), pkt.Page*10)
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
@@ -1157,11 +1154,10 @@ func handleMsgMhfEnumerateGuild(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case mhfpacket.ENUMERATE_GUILD_TYPE_ORDER_RANK:
|
case mhfpacket.ENUMERATE_GUILD_TYPE_ORDER_RANK:
|
||||||
sorting := bf.ReadUint8()
|
if pkt.Sorting {
|
||||||
if sorting == 1 {
|
rows, err = s.server.db.Queryx(fmt.Sprintf(`%s ORDER BY rank_rp DESC OFFSET $1 LIMIT 11`, guildInfoSelectQuery), pkt.Page*10)
|
||||||
rows, err = s.server.db.Queryx(fmt.Sprintf(`%s ORDER BY rank_rp DESC OFFSET $1`, guildInfoSelectQuery), pkt.Page*10)
|
|
||||||
} else {
|
} else {
|
||||||
rows, err = s.server.db.Queryx(fmt.Sprintf(`%s ORDER BY rank_rp ASC OFFSET $1`, guildInfoSelectQuery), pkt.Page*10)
|
rows, err = s.server.db.Queryx(fmt.Sprintf(`%s ORDER BY rank_rp ASC OFFSET $1 LIMIT 11`, guildInfoSelectQuery), pkt.Page*10)
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
@@ -1170,10 +1166,9 @@ func handleMsgMhfEnumerateGuild(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case mhfpacket.ENUMERATE_GUILD_TYPE_MOTTO:
|
case mhfpacket.ENUMERATE_GUILD_TYPE_MOTTO:
|
||||||
bf.ReadBytes(2)
|
|
||||||
mainMotto := bf.ReadUint16()
|
mainMotto := bf.ReadUint16()
|
||||||
subMotto := bf.ReadUint16()
|
subMotto := bf.ReadUint16()
|
||||||
rows, err = s.server.db.Queryx(fmt.Sprintf(`%s WHERE main_motto = $1 AND sub_motto = $2 OFFSET $3`, guildInfoSelectQuery), mainMotto, subMotto, pkt.Page*10)
|
rows, err = s.server.db.Queryx(fmt.Sprintf(`%s WHERE main_motto = $1 AND sub_motto = $2 OFFSET $3 LIMIT 11`, guildInfoSelectQuery), mainMotto, subMotto, pkt.Page*10)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
guild, _ := buildGuildObjectFromDbResult(rows, err, s)
|
guild, _ := buildGuildObjectFromDbResult(rows, err, s)
|
||||||
@@ -1182,37 +1177,114 @@ func handleMsgMhfEnumerateGuild(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
case mhfpacket.ENUMERATE_GUILD_TYPE_RECRUITING:
|
case mhfpacket.ENUMERATE_GUILD_TYPE_RECRUITING:
|
||||||
// Assume the player wants the newest guilds with open recruitment
|
// Assume the player wants the newest guilds with open recruitment
|
||||||
rows, err = s.server.db.Queryx(fmt.Sprintf(`%s WHERE recruiting=true ORDER BY id DESC OFFSET $1`, guildInfoSelectQuery), pkt.Page*10)
|
rows, err = s.server.db.Queryx(fmt.Sprintf(`%s WHERE recruiting=true ORDER BY id DESC OFFSET $1 LIMIT 11`, guildInfoSelectQuery), pkt.Page*10)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
guild, _ := buildGuildObjectFromDbResult(rows, err, s)
|
guild, _ := buildGuildObjectFromDbResult(rows, err, s)
|
||||||
guilds = append(guilds, guild)
|
guilds = append(guilds, guild)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case mhfpacket.ENUMERATE_ALLIANCE_TYPE_ALLIANCE_NAME:
|
|
||||||
//
|
|
||||||
case mhfpacket.ENUMERATE_ALLIANCE_TYPE_LEADER_NAME:
|
|
||||||
//
|
|
||||||
case mhfpacket.ENUMERATE_ALLIANCE_TYPE_LEADER_ID:
|
|
||||||
//
|
|
||||||
case mhfpacket.ENUMERATE_ALLIANCE_TYPE_ORDER_MEMBERS:
|
|
||||||
//
|
|
||||||
case mhfpacket.ENUMERATE_ALLIANCE_TYPE_ORDER_REGISTRATION:
|
|
||||||
//
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("no handler for guild search type '%d'", pkt.Type))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil || guilds == nil {
|
if pkt.Type > 8 {
|
||||||
|
var tempAlliances []*GuildAlliance
|
||||||
|
rows, err = s.server.db.Queryx(allianceInfoSelectQuery)
|
||||||
|
if err == nil {
|
||||||
|
for rows.Next() {
|
||||||
|
alliance, _ := buildAllianceObjectFromDbResult(rows, err, s)
|
||||||
|
tempAlliances = append(tempAlliances, alliance)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch pkt.Type {
|
||||||
|
case mhfpacket.ENUMERATE_ALLIANCE_TYPE_ALLIANCE_NAME:
|
||||||
|
bf.ReadBytes(8)
|
||||||
|
searchTerm := stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes())
|
||||||
|
for _, alliance := range tempAlliances {
|
||||||
|
if strings.Contains(alliance.Name, searchTerm) {
|
||||||
|
alliances = append(alliances, alliance)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case mhfpacket.ENUMERATE_ALLIANCE_TYPE_LEADER_NAME:
|
||||||
|
bf.ReadBytes(8)
|
||||||
|
searchTerm := stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes())
|
||||||
|
for _, alliance := range tempAlliances {
|
||||||
|
if strings.Contains(alliance.ParentGuild.LeaderName, searchTerm) {
|
||||||
|
alliances = append(alliances, alliance)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case mhfpacket.ENUMERATE_ALLIANCE_TYPE_LEADER_ID:
|
||||||
|
ID := bf.ReadUint32()
|
||||||
|
for _, alliance := range tempAlliances {
|
||||||
|
if alliance.ParentGuild.LeaderCharID == ID {
|
||||||
|
alliances = append(alliances, alliance)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case mhfpacket.ENUMERATE_ALLIANCE_TYPE_ORDER_MEMBERS:
|
||||||
|
if pkt.Sorting {
|
||||||
|
sort.Slice(tempAlliances, func(i, j int) bool {
|
||||||
|
return tempAlliances[i].TotalMembers > tempAlliances[j].TotalMembers
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
sort.Slice(tempAlliances, func(i, j int) bool {
|
||||||
|
return tempAlliances[i].TotalMembers < tempAlliances[j].TotalMembers
|
||||||
|
})
|
||||||
|
}
|
||||||
|
alliances = tempAlliances
|
||||||
|
case mhfpacket.ENUMERATE_ALLIANCE_TYPE_ORDER_REGISTRATION:
|
||||||
|
if pkt.Sorting {
|
||||||
|
sort.Slice(tempAlliances, func(i, j int) bool {
|
||||||
|
return tempAlliances[i].CreatedAt.Unix() > tempAlliances[j].CreatedAt.Unix()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
sort.Slice(tempAlliances, func(i, j int) bool {
|
||||||
|
return tempAlliances[i].CreatedAt.Unix() < tempAlliances[j].CreatedAt.Unix()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
alliances = tempAlliances
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil || (guilds == nil && alliances == nil) {
|
||||||
stubEnumerateNoResults(s, pkt.AckHandle)
|
stubEnumerateNoResults(s, pkt.AckHandle)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
bf = byteframe.NewByteFrame()
|
bf = byteframe.NewByteFrame()
|
||||||
bf.WriteUint16(uint16(len(guilds)))
|
|
||||||
|
|
||||||
|
if pkt.Type > 8 {
|
||||||
|
hasNextPage := false
|
||||||
|
if len(alliances) > 10 {
|
||||||
|
hasNextPage = true
|
||||||
|
alliances = alliances[:10]
|
||||||
|
}
|
||||||
|
bf.WriteUint16(uint16(len(alliances)))
|
||||||
|
bf.WriteBool(hasNextPage)
|
||||||
|
for _, alliance := range alliances {
|
||||||
|
bf.WriteUint32(alliance.ID)
|
||||||
|
bf.WriteUint32(alliance.ParentGuild.LeaderCharID)
|
||||||
|
bf.WriteUint16(alliance.TotalMembers)
|
||||||
|
bf.WriteUint16(0x0000)
|
||||||
|
if alliance.SubGuild1ID == 0 && alliance.SubGuild2ID == 0 {
|
||||||
|
bf.WriteUint16(1)
|
||||||
|
} else if alliance.SubGuild1ID > 0 && alliance.SubGuild2ID == 0 || alliance.SubGuild1ID == 0 && alliance.SubGuild2ID > 0 {
|
||||||
|
bf.WriteUint16(2)
|
||||||
|
} else {
|
||||||
|
bf.WriteUint16(3)
|
||||||
|
}
|
||||||
|
bf.WriteUint32(uint32(alliance.CreatedAt.Unix()))
|
||||||
|
ps.Uint8(bf, alliance.Name, true)
|
||||||
|
ps.Uint8(bf, alliance.ParentGuild.LeaderName, true)
|
||||||
bf.WriteUint8(0x01) // Unk
|
bf.WriteUint8(0x01) // Unk
|
||||||
|
bf.WriteBool(true) // TODO: Enable GuildAlliance applications
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
hasNextPage := false
|
||||||
|
if len(guilds) > 10 {
|
||||||
|
hasNextPage = true
|
||||||
|
guilds = guilds[:10]
|
||||||
|
}
|
||||||
|
bf.WriteUint16(uint16(len(guilds)))
|
||||||
|
bf.WriteBool(hasNextPage)
|
||||||
for _, guild := range guilds {
|
for _, guild := range guilds {
|
||||||
bf.WriteUint32(guild.ID)
|
bf.WriteUint32(guild.ID)
|
||||||
bf.WriteUint32(guild.LeaderCharID)
|
bf.WriteUint32(guild.LeaderCharID)
|
||||||
@@ -1225,6 +1297,7 @@ func handleMsgMhfEnumerateGuild(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
bf.WriteUint8(0x01) // Unk
|
bf.WriteUint8(0x01) // Unk
|
||||||
bf.WriteBool(!guild.Recruiting)
|
bf.WriteBool(!guild.Recruiting)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||||
}
|
}
|
||||||
@@ -1712,14 +1785,29 @@ func handleMsgMhfGetGuildWeeklyBonusMaster(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
func handleMsgMhfGetGuildWeeklyBonusActiveCount(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfGetGuildWeeklyBonusActiveCount(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfGetGuildWeeklyBonusActiveCount)
|
pkt := p.(*mhfpacket.MsgMhfGetGuildWeeklyBonusActiveCount)
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
// Values taken from brand new guild capture
|
bf.WriteUint8(0x3C) // Active count
|
||||||
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 0x03))
|
bf.WriteUint8(0x3C) // Current active count
|
||||||
|
bf.WriteUint8(0x00) // New active count
|
||||||
|
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfGuildHuntdata(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfGuildHuntdata(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfGuildHuntdata)
|
pkt := p.(*mhfpacket.MsgMhfGuildHuntdata)
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
bf := byteframe.NewByteFrame()
|
||||||
|
switch pkt.Operation {
|
||||||
|
case 0: // Unk
|
||||||
|
doAckBufSucceed(s, pkt.AckHandle, []byte{})
|
||||||
|
case 1: // Get Huntdata
|
||||||
|
bf.WriteUint8(0) // Entries
|
||||||
|
/* Entry format
|
||||||
|
uint32 UnkID
|
||||||
|
uint32 MonID
|
||||||
|
*/
|
||||||
|
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||||
|
case 2: // Unk, controls glow
|
||||||
|
doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type MessageBoardPost struct {
|
type MessageBoardPost struct {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package channelserver
|
package channelserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"erupe-ce/common/byteframe"
|
||||||
|
ps "erupe-ce/common/pascalstring"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -139,8 +141,15 @@ func handleMsgMhfOperateJoint(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
case mhfpacket.OPERATE_JOINT_LEAVE:
|
case mhfpacket.OPERATE_JOINT_LEAVE:
|
||||||
if guild.LeaderCharID == s.charID {
|
if guild.LeaderCharID == s.charID {
|
||||||
// delete alliance application
|
if guild.ID == alliance.SubGuild1ID && alliance.SubGuild2ID > 0 {
|
||||||
// or leave alliance
|
s.server.db.Exec(`UPDATE guild_alliances SET sub1_id = sub2_id, sub2_id = NULL WHERE id = $1`, alliance.ID)
|
||||||
|
} else if guild.ID == alliance.SubGuild1ID && alliance.SubGuild2ID == 0 {
|
||||||
|
s.server.db.Exec(`UPDATE guild_alliances SET sub1_id = NULL WHERE id = $1`, alliance.ID)
|
||||||
|
} else {
|
||||||
|
s.server.db.Exec(`UPDATE guild_alliances SET sub2_id = NULL WHERE id = $1`, alliance.ID)
|
||||||
|
}
|
||||||
|
// TODO: Handle deleting Alliance applications
|
||||||
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
} else {
|
} else {
|
||||||
s.logger.Warn(
|
s.logger.Warn(
|
||||||
"Non-owner of guild attempted alliance leave",
|
"Non-owner of guild attempted alliance leave",
|
||||||
@@ -148,10 +157,75 @@ func handleMsgMhfOperateJoint(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
)
|
)
|
||||||
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
||||||
}
|
}
|
||||||
default:
|
case mhfpacket.OPERATE_JOINT_KICK:
|
||||||
panic(fmt.Sprintf("Unhandled operate joint action '%d'", pkt.Action))
|
if alliance.ParentGuild.LeaderCharID == s.charID {
|
||||||
|
_ = pkt.UnkData.ReadUint8()
|
||||||
|
kickedGuildID := pkt.UnkData.ReadUint32()
|
||||||
|
if kickedGuildID == alliance.SubGuild1ID && alliance.SubGuild2ID > 0 {
|
||||||
|
s.server.db.Exec(`UPDATE guild_alliances SET sub1_id = sub2_id, sub2_id = NULL WHERE id = $1`, alliance.ID)
|
||||||
|
} else if kickedGuildID == alliance.SubGuild1ID && alliance.SubGuild2ID == 0 {
|
||||||
|
s.server.db.Exec(`UPDATE guild_alliances SET sub1_id = NULL WHERE id = $1`, alliance.ID)
|
||||||
|
} else {
|
||||||
|
s.server.db.Exec(`UPDATE guild_alliances SET sub2_id = NULL WHERE id = $1`, alliance.ID)
|
||||||
|
}
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
|
} else {
|
||||||
|
s.logger.Warn(
|
||||||
|
"Non-owner of alliance attempted kick",
|
||||||
|
zap.Uint32("CharID", s.charID),
|
||||||
|
zap.Uint32("AllyID", alliance.ID),
|
||||||
|
)
|
||||||
|
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
|
panic(fmt.Sprintf("Unhandled operate joint action '%d'", pkt.Action))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfInfoJoint(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgMhfInfoJoint(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
pkt := p.(*mhfpacket.MsgMhfInfoJoint)
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
alliance, err := GetAllianceData(s, pkt.AllianceID)
|
||||||
|
if err != nil {
|
||||||
|
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
||||||
|
} else {
|
||||||
|
bf.WriteUint32(alliance.ID)
|
||||||
|
bf.WriteUint32(uint32(alliance.CreatedAt.Unix()))
|
||||||
|
bf.WriteUint16(alliance.TotalMembers)
|
||||||
|
bf.WriteUint16(0x0000) // Unk
|
||||||
|
ps.Uint16(bf, alliance.Name, true)
|
||||||
|
if alliance.SubGuild1ID > 0 {
|
||||||
|
if alliance.SubGuild2ID > 0 {
|
||||||
|
bf.WriteUint8(3)
|
||||||
|
} else {
|
||||||
|
bf.WriteUint8(2)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bf.WriteUint8(1)
|
||||||
|
}
|
||||||
|
bf.WriteUint32(alliance.ParentGuildID)
|
||||||
|
bf.WriteUint32(alliance.ParentGuild.LeaderCharID)
|
||||||
|
bf.WriteUint16(alliance.ParentGuild.Rank)
|
||||||
|
bf.WriteUint16(alliance.ParentGuild.MemberCount)
|
||||||
|
ps.Uint16(bf, alliance.ParentGuild.Name, true)
|
||||||
|
ps.Uint16(bf, alliance.ParentGuild.LeaderName, true)
|
||||||
|
if alliance.SubGuild1ID > 0 {
|
||||||
|
bf.WriteUint32(alliance.SubGuild1ID)
|
||||||
|
bf.WriteUint32(alliance.SubGuild1.LeaderCharID)
|
||||||
|
bf.WriteUint16(alliance.SubGuild1.Rank)
|
||||||
|
bf.WriteUint16(alliance.SubGuild1.MemberCount)
|
||||||
|
ps.Uint16(bf, alliance.SubGuild1.Name, true)
|
||||||
|
ps.Uint16(bf, alliance.SubGuild1.LeaderName, true)
|
||||||
|
}
|
||||||
|
if alliance.SubGuild2ID > 0 {
|
||||||
|
bf.WriteUint32(alliance.SubGuild2ID)
|
||||||
|
bf.WriteUint32(alliance.SubGuild2.LeaderCharID)
|
||||||
|
bf.WriteUint16(alliance.SubGuild2.Rank)
|
||||||
|
bf.WriteUint16(alliance.SubGuild2.MemberCount)
|
||||||
|
ps.Uint16(bf, alliance.SubGuild2.Name, true)
|
||||||
|
ps.Uint16(bf, alliance.SubGuild2.LeaderName, true)
|
||||||
|
}
|
||||||
|
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -38,10 +38,7 @@ FROM warehouse
|
|||||||
|
|
||||||
func handleMsgMhfUpdateInterior(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfUpdateInterior(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfUpdateInterior)
|
pkt := p.(*mhfpacket.MsgMhfUpdateInterior)
|
||||||
_, err := s.server.db.Exec("UPDATE characters SET house=$1 WHERE id=$2", pkt.InteriorData, s.charID)
|
s.server.db.Exec(`UPDATE user_binary SET house_furniture=$1 WHERE id=$2`, pkt.InteriorData, s.charID)
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,12 +47,17 @@ type HouseData struct {
|
|||||||
HRP uint16 `db:"hrp"`
|
HRP uint16 `db:"hrp"`
|
||||||
GR uint16 `db:"gr"`
|
GR uint16 `db:"gr"`
|
||||||
Name string `db:"name"`
|
Name string `db:"name"`
|
||||||
|
HouseState uint8 `db:"house_state"`
|
||||||
|
HousePassword string `db:"house_password"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfEnumerateHouse(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfEnumerateHouse(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfEnumerateHouse)
|
pkt := p.(*mhfpacket.MsgMhfEnumerateHouse)
|
||||||
bf := byteframe.NewByteFrame()
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteUint16(0)
|
||||||
var houses []HouseData
|
var houses []HouseData
|
||||||
|
houseQuery := `SELECT c.id, hrp, gr, name, COALESCE(ub.house_state, 2) as house_state, COALESCE(ub.house_password, '') as house_password
|
||||||
|
FROM characters c LEFT JOIN user_binary ub ON ub.id = c.id WHERE c.id=$1`
|
||||||
switch pkt.Method {
|
switch pkt.Method {
|
||||||
case 1:
|
case 1:
|
||||||
var friendsList string
|
var friendsList string
|
||||||
@@ -63,17 +65,15 @@ func handleMsgMhfEnumerateHouse(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
cids := stringsupport.CSVElems(friendsList)
|
cids := stringsupport.CSVElems(friendsList)
|
||||||
for _, cid := range cids {
|
for _, cid := range cids {
|
||||||
house := HouseData{}
|
house := HouseData{}
|
||||||
row := s.server.db.QueryRowx("SELECT id, hrp, gr, name FROM characters WHERE id=$1", cid)
|
row := s.server.db.QueryRowx(houseQuery, cid)
|
||||||
err := row.StructScan(&house)
|
err := row.StructScan(&house)
|
||||||
if err != nil {
|
if err == nil {
|
||||||
panic(err)
|
|
||||||
} else {
|
|
||||||
houses = append(houses, house)
|
houses = append(houses, house)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
guild, err := GetGuildInfoByCharacterId(s, s.charID)
|
guild, err := GetGuildInfoByCharacterId(s, s.charID)
|
||||||
if err != nil {
|
if err != nil || guild == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
guildMembers, err := GetGuildMembers(s, guild.ID, false)
|
guildMembers, err := GetGuildMembers(s, guild.ID, false)
|
||||||
@@ -82,43 +82,37 @@ func handleMsgMhfEnumerateHouse(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
for _, member := range guildMembers {
|
for _, member := range guildMembers {
|
||||||
house := HouseData{}
|
house := HouseData{}
|
||||||
row := s.server.db.QueryRowx("SELECT id, hrp, gr, name FROM characters WHERE id=$1", member.CharID)
|
row := s.server.db.QueryRowx(houseQuery, member.CharID)
|
||||||
err := row.StructScan(&house)
|
err = row.StructScan(&house)
|
||||||
if err != nil {
|
if err == nil {
|
||||||
panic(err)
|
|
||||||
} else {
|
|
||||||
houses = append(houses, house)
|
houses = append(houses, house)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case 3:
|
case 3:
|
||||||
|
houseQuery = `SELECT c.id, hrp, gr, name, COALESCE(ub.house_state, 2) as house_state, COALESCE(ub.house_password, '') as house_password
|
||||||
|
FROM characters c LEFT JOIN user_binary ub ON ub.id = c.id WHERE name ILIKE $1`
|
||||||
house := HouseData{}
|
house := HouseData{}
|
||||||
row := s.server.db.QueryRowx("SELECT id, hrp, gr, name FROM characters WHERE name ILIKE $1", fmt.Sprintf(`%%%s%%`, pkt.Name))
|
rows, _ := s.server.db.Queryx(houseQuery, fmt.Sprintf(`%%%s%%`, pkt.Name))
|
||||||
err := row.StructScan(&house)
|
for rows.Next() {
|
||||||
if err != nil {
|
err := rows.StructScan(&house)
|
||||||
panic(err)
|
if err == nil {
|
||||||
} else {
|
|
||||||
houses = append(houses, house)
|
houses = append(houses, house)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
case 4:
|
case 4:
|
||||||
house := HouseData{}
|
house := HouseData{}
|
||||||
row := s.server.db.QueryRowx("SELECT id, hrp, gr, name FROM characters WHERE id=$1", pkt.CharID)
|
row := s.server.db.QueryRowx(houseQuery, pkt.CharID)
|
||||||
err := row.StructScan(&house)
|
err := row.StructScan(&house)
|
||||||
if err != nil {
|
if err == nil {
|
||||||
panic(err)
|
|
||||||
} else {
|
|
||||||
houses = append(houses, house)
|
houses = append(houses, house)
|
||||||
}
|
}
|
||||||
case 5: // Recent visitors
|
case 5: // Recent visitors
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
var exists int
|
|
||||||
for _, house := range houses {
|
for _, house := range houses {
|
||||||
for _, session := range s.server.sessions {
|
|
||||||
if session.charID == house.CharID {
|
|
||||||
exists++
|
|
||||||
bf.WriteUint32(house.CharID)
|
bf.WriteUint32(house.CharID)
|
||||||
bf.WriteUint8(session.myseries.state)
|
bf.WriteUint8(house.HouseState)
|
||||||
if len(session.myseries.password) > 0 {
|
if len(house.HousePassword) > 0 {
|
||||||
bf.WriteUint8(3)
|
bf.WriteUint8(3)
|
||||||
} else {
|
} else {
|
||||||
bf.WriteUint8(0)
|
bf.WriteUint8(0)
|
||||||
@@ -126,14 +120,10 @@ func handleMsgMhfEnumerateHouse(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
bf.WriteUint16(house.HRP)
|
bf.WriteUint16(house.HRP)
|
||||||
bf.WriteUint16(house.GR)
|
bf.WriteUint16(house.GR)
|
||||||
ps.Uint8(bf, house.Name, true)
|
ps.Uint8(bf, house.Name, true)
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
bf.Seek(0, 0)
|
||||||
}
|
bf.WriteUint16(uint16(len(houses)))
|
||||||
resp := byteframe.NewByteFrame()
|
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||||
resp.WriteUint16(uint16(exists))
|
|
||||||
resp.WriteBytes(bf.Data())
|
|
||||||
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfUpdateHouse(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfUpdateHouse(s *Session, p mhfpacket.MHFPacket) {
|
||||||
@@ -143,73 +133,90 @@ func handleMsgMhfUpdateHouse(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
// 03 = open friends
|
// 03 = open friends
|
||||||
// 04 = open guild
|
// 04 = open guild
|
||||||
// 05 = open friends+guild
|
// 05 = open friends+guild
|
||||||
s.myseries.state = pkt.State
|
s.server.db.Exec(`UPDATE user_binary SET house_state=$1, house_password=$2 WHERE id=$3`, pkt.State, pkt.Password, s.charID)
|
||||||
s.myseries.password = pkt.Password
|
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfLoadHouse(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfLoadHouse(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfLoadHouse)
|
pkt := p.(*mhfpacket.MsgMhfLoadHouse)
|
||||||
bf := byteframe.NewByteFrame()
|
bf := byteframe.NewByteFrame()
|
||||||
|
|
||||||
|
var state uint8
|
||||||
|
var password string
|
||||||
|
s.server.db.QueryRow(`SELECT COALESCE(house_state, 2) as house_state, COALESCE(house_password, '') as house_password FROM user_binary WHERE id=$1
|
||||||
|
`, pkt.CharID).Scan(&state, &password)
|
||||||
|
|
||||||
if pkt.Destination != 9 && len(pkt.Password) > 0 && pkt.CheckPass {
|
if pkt.Destination != 9 && len(pkt.Password) > 0 && pkt.CheckPass {
|
||||||
for _, session := range s.server.sessions {
|
if pkt.Password != password {
|
||||||
if session.charID == pkt.CharID && pkt.Password != session.myseries.password {
|
|
||||||
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if pkt.Destination != 9 && state > 2 {
|
||||||
|
allowed := false
|
||||||
|
|
||||||
|
// Friends list verification
|
||||||
|
if state == 3 || state == 5 {
|
||||||
|
var friendsList string
|
||||||
|
s.server.db.QueryRow(`SELECT friends FROM characters WHERE id=$1`, pkt.CharID).Scan(&friendsList)
|
||||||
|
cids := stringsupport.CSVElems(friendsList)
|
||||||
|
for _, cid := range cids {
|
||||||
|
if uint32(cid) == s.charID {
|
||||||
|
allowed = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var furniture []byte
|
// Guild verification
|
||||||
err := s.server.db.QueryRow("SELECT house FROM characters WHERE id=$1", pkt.CharID).Scan(&furniture)
|
if state > 3 {
|
||||||
if err != nil {
|
ownGuild, err := GetGuildInfoByCharacterId(s, s.charID)
|
||||||
panic(err)
|
isApplicant, _ := ownGuild.HasApplicationForCharID(s, s.charID)
|
||||||
|
if err == nil && ownGuild != nil {
|
||||||
|
othersGuild, err := GetGuildInfoByCharacterId(s, pkt.CharID)
|
||||||
|
if err == nil && othersGuild != nil {
|
||||||
|
if othersGuild.ID == ownGuild.ID && !isApplicant {
|
||||||
|
allowed = true
|
||||||
}
|
}
|
||||||
if furniture == nil {
|
}
|
||||||
furniture = make([]byte, 20)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !allowed {
|
||||||
|
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var houseTier, houseData, houseFurniture, bookshelf, gallery, tore, garden []byte
|
||||||
|
s.server.db.QueryRow(`SELECT house_tier, house_data, house_furniture, bookshelf, gallery, tore, garden FROM user_binary WHERE id=$1
|
||||||
|
`, pkt.CharID).Scan(&houseTier, &houseData, &houseFurniture, &bookshelf, &gallery, &tore, &garden)
|
||||||
|
if houseFurniture == nil {
|
||||||
|
houseFurniture = make([]byte, 20)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch pkt.Destination {
|
switch pkt.Destination {
|
||||||
case 3: // Others house
|
case 3: // Others house
|
||||||
for _, session := range s.server.sessions {
|
bf.WriteBytes(houseTier)
|
||||||
if session.charID == pkt.CharID {
|
bf.WriteBytes(houseData)
|
||||||
bf.WriteBytes(session.myseries.houseTier)
|
|
||||||
bf.WriteBytes(session.myseries.houseData)
|
|
||||||
bf.WriteBytes(make([]byte, 19)) // Padding?
|
bf.WriteBytes(make([]byte, 19)) // Padding?
|
||||||
bf.WriteBytes(furniture)
|
bf.WriteBytes(houseFurniture)
|
||||||
}
|
|
||||||
}
|
|
||||||
case 4: // Bookshelf
|
case 4: // Bookshelf
|
||||||
for _, session := range s.server.sessions {
|
bf.WriteBytes(bookshelf)
|
||||||
if session.charID == pkt.CharID {
|
|
||||||
bf.WriteBytes(session.myseries.bookshelfData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 5: // Gallery
|
case 5: // Gallery
|
||||||
for _, session := range s.server.sessions {
|
bf.WriteBytes(gallery)
|
||||||
if session.charID == pkt.CharID {
|
|
||||||
bf.WriteBytes(session.myseries.galleryData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 8: // Tore
|
case 8: // Tore
|
||||||
for _, session := range s.server.sessions {
|
bf.WriteBytes(tore)
|
||||||
if session.charID == pkt.CharID {
|
|
||||||
bf.WriteBytes(session.myseries.toreData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case 9: // Own house
|
case 9: // Own house
|
||||||
bf.WriteBytes(furniture)
|
bf.WriteBytes(houseFurniture)
|
||||||
case 10: // Garden
|
case 10: // Garden
|
||||||
for _, session := range s.server.sessions {
|
bf.WriteBytes(garden)
|
||||||
if session.charID == pkt.CharID {
|
|
||||||
bf.WriteBytes(session.myseries.gardenData)
|
|
||||||
c, d := getGookData(s, pkt.CharID)
|
c, d := getGookData(s, pkt.CharID)
|
||||||
bf.WriteUint16(c)
|
bf.WriteUint16(c)
|
||||||
bf.WriteUint16(0)
|
bf.WriteUint16(0)
|
||||||
bf.WriteBytes(d)
|
bf.WriteBytes(d)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(bf.Data()) == 0 {
|
if len(bf.Data()) == 0 {
|
||||||
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
||||||
} else {
|
} else {
|
||||||
@@ -219,26 +226,18 @@ func handleMsgMhfLoadHouse(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
|
|
||||||
func handleMsgMhfGetMyhouseInfo(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfGetMyhouseInfo(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfGetMyhouseInfo)
|
pkt := p.(*mhfpacket.MsgMhfGetMyhouseInfo)
|
||||||
|
|
||||||
var data []byte
|
var data []byte
|
||||||
err := s.server.db.QueryRow("SELECT trophy FROM characters WHERE id = $1", s.charID).Scan(&data)
|
s.server.db.QueryRow(`SELECT mission FROM user_binary WHERE id=$1`, s.charID).Scan(&data)
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
if len(data) > 0 {
|
if len(data) > 0 {
|
||||||
doAckBufSucceed(s, pkt.AckHandle, data)
|
doAckBufSucceed(s, pkt.AckHandle, data)
|
||||||
} else {
|
} else {
|
||||||
doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
|
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 9))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfUpdateMyhouseInfo(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfUpdateMyhouseInfo(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfUpdateMyhouseInfo)
|
pkt := p.(*mhfpacket.MsgMhfUpdateMyhouseInfo)
|
||||||
|
s.server.db.Exec("UPDATE user_binary SET mission=$1 WHERE id=$2", pkt.Unk0, s.charID)
|
||||||
_, err := s.server.db.Exec("UPDATE characters SET trophy=$1 WHERE id=$2", pkt.Unk0, s.charID)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,6 +310,7 @@ func handleMsgMhfSaveDecoMyset(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
loadData[1] = savedSets // update set count
|
loadData[1] = savedSets // update set count
|
||||||
}
|
}
|
||||||
|
dumpSaveData(s, loadData, "decomyset")
|
||||||
_, err := s.server.db.Exec("UPDATE characters SET decomyset=$1 WHERE id=$2", loadData, s.charID)
|
_, err := s.server.db.Exec("UPDATE characters SET decomyset=$1 WHERE id=$2", loadData, s.charID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Fatal("Failed to update decomyset savedata in db", zap.Error(err))
|
s.logger.Fatal("Failed to update decomyset savedata in db", zap.Error(err))
|
||||||
|
|||||||
@@ -104,6 +104,7 @@ func handleMsgMhfSaveHunterNavi(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
|
|
||||||
s.logger.Info("Wrote recompressed hunternavi back to DB.")
|
s.logger.Info("Wrote recompressed hunternavi back to DB.")
|
||||||
} else {
|
} else {
|
||||||
|
dumpSaveData(s, pkt.RawDataPayload, "hunternavi")
|
||||||
// simply update database, no extra processing
|
// simply update database, no extra processing
|
||||||
_, err := s.server.db.Exec("UPDATE characters SET hunternavi=$1 WHERE id=$2", pkt.RawDataPayload, s.charID)
|
_, err := s.server.db.Exec("UPDATE characters SET hunternavi=$1 WHERE id=$2", pkt.RawDataPayload, s.charID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -162,6 +163,7 @@ func handleMsgMhfCreateMercenary(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
|
|
||||||
func handleMsgMhfSaveMercenary(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfSaveMercenary(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfSaveMercenary)
|
pkt := p.(*mhfpacket.MsgMhfSaveMercenary)
|
||||||
|
dumpSaveData(s, pkt.MercData, "mercenary")
|
||||||
if len(pkt.MercData) > 0 {
|
if len(pkt.MercData) > 0 {
|
||||||
s.server.db.Exec("UPDATE characters SET savemercenary=$1 WHERE id=$2", pkt.MercData, s.charID)
|
s.server.db.Exec("UPDATE characters SET savemercenary=$1 WHERE id=$2", pkt.MercData, s.charID)
|
||||||
}
|
}
|
||||||
@@ -236,19 +238,31 @@ func handleMsgMhfSaveOtomoAirou(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
bf := byteframe.NewByteFrameFromBytes(decomp)
|
bf := byteframe.NewByteFrameFromBytes(decomp)
|
||||||
|
save := byteframe.NewByteFrame()
|
||||||
|
var catsExist uint8
|
||||||
|
save.WriteUint8(0)
|
||||||
|
|
||||||
cats := bf.ReadUint8()
|
cats := bf.ReadUint8()
|
||||||
for i := 0; i < int(cats); i++ {
|
for i := 0; i < int(cats); i++ {
|
||||||
dataLen := bf.ReadUint32()
|
dataLen := bf.ReadUint32()
|
||||||
catID := bf.ReadUint32()
|
catID := bf.ReadUint32()
|
||||||
if catID == 0 {
|
if catID == 0 {
|
||||||
var nextID uint32
|
_ = s.server.db.QueryRow("SELECT nextval('airou_id_seq')").Scan(&catID)
|
||||||
_ = s.server.db.QueryRow("SELECT nextval('airou_id_seq')").Scan(&nextID)
|
|
||||||
bf.Seek(-4, io.SeekCurrent)
|
|
||||||
bf.WriteUint32(nextID)
|
|
||||||
}
|
}
|
||||||
_ = bf.ReadBytes(uint(dataLen) - 4)
|
exists := bf.ReadBool()
|
||||||
|
data := bf.ReadBytes(uint(dataLen) - 5)
|
||||||
|
if exists {
|
||||||
|
catsExist++
|
||||||
|
save.WriteUint32(dataLen)
|
||||||
|
save.WriteUint32(catID)
|
||||||
|
save.WriteBool(exists)
|
||||||
|
save.WriteBytes(data)
|
||||||
}
|
}
|
||||||
comp, err := nullcomp.Compress(bf.Data())
|
}
|
||||||
|
save.WriteBytes(bf.DataFromCurrent())
|
||||||
|
save.Seek(0, 0)
|
||||||
|
save.WriteUint8(catsExist)
|
||||||
|
comp, err := nullcomp.Compress(save.Data())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Error("Failed to compress airou", zap.Error(err))
|
s.logger.Error("Failed to compress airou", zap.Error(err))
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -12,20 +12,20 @@ func handleMsgMhfLoadPlateData(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
var data []byte
|
var data []byte
|
||||||
err := s.server.db.QueryRow("SELECT platedata FROM characters WHERE id = $1", s.charID).Scan(&data)
|
err := s.server.db.QueryRow("SELECT platedata FROM characters WHERE id = $1", s.charID).Scan(&data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Fatal("Failed to get plate data savedata from db", zap.Error(err))
|
s.logger.Error("Failed to get plate data savedata from db", zap.Error(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(data) > 0 {
|
if len(data) > 0 {
|
||||||
doAckBufSucceed(s, pkt.AckHandle, data)
|
doAckBufSucceed(s, pkt.AckHandle, data)
|
||||||
} else {
|
} else {
|
||||||
doAckBufSucceed(s, pkt.AckHandle, []byte{})
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfSavePlateData(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfSavePlateData(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfSavePlateData)
|
pkt := p.(*mhfpacket.MsgMhfSavePlateData)
|
||||||
|
|
||||||
dumpSaveData(s, pkt.RawDataPayload, "_platedata")
|
dumpSaveData(s, pkt.RawDataPayload, "platedata")
|
||||||
|
|
||||||
if pkt.IsDataDiff {
|
if pkt.IsDataDiff {
|
||||||
var data []byte
|
var data []byte
|
||||||
@@ -77,20 +77,20 @@ func handleMsgMhfLoadPlateBox(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
var data []byte
|
var data []byte
|
||||||
err := s.server.db.QueryRow("SELECT platebox FROM characters WHERE id = $1", s.charID).Scan(&data)
|
err := s.server.db.QueryRow("SELECT platebox FROM characters WHERE id = $1", s.charID).Scan(&data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Fatal("Failed to get sigil box savedata from db", zap.Error(err))
|
s.logger.Error("Failed to get sigil box savedata from db", zap.Error(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(data) > 0 {
|
if len(data) > 0 {
|
||||||
doAckBufSucceed(s, pkt.AckHandle, data)
|
doAckBufSucceed(s, pkt.AckHandle, data)
|
||||||
} else {
|
} else {
|
||||||
doAckBufSucceed(s, pkt.AckHandle, []byte{})
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfSavePlateBox(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfSavePlateBox(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfSavePlateBox)
|
pkt := p.(*mhfpacket.MsgMhfSavePlateBox)
|
||||||
|
|
||||||
dumpSaveData(s, pkt.RawDataPayload, "_platebox")
|
dumpSaveData(s, pkt.RawDataPayload, "platebox")
|
||||||
|
|
||||||
if pkt.IsDataDiff {
|
if pkt.IsDataDiff {
|
||||||
var data []byte
|
var data []byte
|
||||||
@@ -156,7 +156,7 @@ func handleMsgMhfLoadPlateMyset(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
func handleMsgMhfSavePlateMyset(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfSavePlateMyset(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfSavePlateMyset)
|
pkt := p.(*mhfpacket.MsgMhfSavePlateMyset)
|
||||||
// looks to always return the full thing, simply update database, no extra processing
|
// looks to always return the full thing, simply update database, no extra processing
|
||||||
|
dumpSaveData(s, pkt.RawDataPayload, "platemyset")
|
||||||
_, err := s.server.db.Exec("UPDATE characters SET platemyset=$1 WHERE id=$2", pkt.RawDataPayload, s.charID)
|
_, err := s.server.db.Exec("UPDATE characters SET platemyset=$1 WHERE id=$2", pkt.RawDataPayload, s.charID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Fatal("Failed to update platemyset savedata in db", zap.Error(err))
|
s.logger.Fatal("Failed to update platemyset savedata in db", zap.Error(err))
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package channelserver
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@@ -14,14 +13,24 @@ import (
|
|||||||
func handleMsgSysGetFile(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgSysGetFile(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgSysGetFile)
|
pkt := p.(*mhfpacket.MsgSysGetFile)
|
||||||
|
|
||||||
// Debug print the request.
|
|
||||||
if pkt.IsScenario {
|
if pkt.IsScenario {
|
||||||
fmt.Printf("%+v\n", pkt.ScenarioIdentifer)
|
if s.server.erupeConfig.DevModeOptions.QuestDebugTools && s.server.erupeConfig.DevMode {
|
||||||
|
s.logger.Debug(
|
||||||
|
"Scenario",
|
||||||
|
zap.Uint8("CategoryID", pkt.ScenarioIdentifer.CategoryID),
|
||||||
|
zap.Uint32("MainID", pkt.ScenarioIdentifer.MainID),
|
||||||
|
zap.Uint8("ChapterID", pkt.ScenarioIdentifer.ChapterID),
|
||||||
|
zap.Uint8("Flags", pkt.ScenarioIdentifer.Flags),
|
||||||
|
)
|
||||||
|
}
|
||||||
filename := fmt.Sprintf("%d_0_0_0_S%d_T%d_C%d", pkt.ScenarioIdentifer.CategoryID, pkt.ScenarioIdentifer.MainID, pkt.ScenarioIdentifer.Flags, pkt.ScenarioIdentifer.ChapterID)
|
filename := fmt.Sprintf("%d_0_0_0_S%d_T%d_C%d", pkt.ScenarioIdentifer.CategoryID, pkt.ScenarioIdentifer.MainID, pkt.ScenarioIdentifer.Flags, pkt.ScenarioIdentifer.ChapterID)
|
||||||
// Read the scenario file.
|
// Read the scenario file.
|
||||||
data, err := ioutil.ReadFile(filepath.Join(s.server.erupeConfig.BinPath, fmt.Sprintf("scenarios/%s.bin", filename)))
|
data, err := ioutil.ReadFile(filepath.Join(s.server.erupeConfig.BinPath, fmt.Sprintf("scenarios/%s.bin", filename)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
s.logger.Error(fmt.Sprintf("Failed to open file: %s/scenarios/%s.bin", s.server.erupeConfig.BinPath, filename))
|
||||||
|
// This will crash the game.
|
||||||
|
doAckBufSucceed(s, pkt.AckHandle, data)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
doAckBufSucceed(s, pkt.AckHandle, data)
|
doAckBufSucceed(s, pkt.AckHandle, data)
|
||||||
} else {
|
} else {
|
||||||
@@ -32,10 +41,19 @@ func handleMsgSysGetFile(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
doAckBufSucceed(s, pkt.AckHandle, data)
|
doAckBufSucceed(s, pkt.AckHandle, data)
|
||||||
} else {
|
} else {
|
||||||
|
if s.server.erupeConfig.DevModeOptions.QuestDebugTools && s.server.erupeConfig.DevMode {
|
||||||
|
s.logger.Debug(
|
||||||
|
"Quest",
|
||||||
|
zap.String("Filename", pkt.Filename),
|
||||||
|
)
|
||||||
|
}
|
||||||
// Get quest file.
|
// Get quest file.
|
||||||
data, err := ioutil.ReadFile(filepath.Join(s.server.erupeConfig.BinPath, fmt.Sprintf("quests/%s.bin", pkt.Filename)))
|
data, err := ioutil.ReadFile(filepath.Join(s.server.erupeConfig.BinPath, fmt.Sprintf("quests/%s.bin", pkt.Filename)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Fatal(fmt.Sprintf("Failed to open quest file: quests/%s.bin", pkt.Filename))
|
s.logger.Error(fmt.Sprintf("Failed to open file: %s/quests/%s.bin", s.server.erupeConfig.BinPath, pkt.Filename))
|
||||||
|
// This will crash the game.
|
||||||
|
doAckBufSucceed(s, pkt.AckHandle, data)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
doAckBufSucceed(s, pkt.AckHandle, data)
|
doAckBufSucceed(s, pkt.AckHandle, data)
|
||||||
}
|
}
|
||||||
@@ -55,6 +73,7 @@ func handleMsgMhfLoadFavoriteQuest(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
|
|
||||||
func handleMsgMhfSaveFavoriteQuest(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfSaveFavoriteQuest(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfSaveFavoriteQuest)
|
pkt := p.(*mhfpacket.MsgMhfSaveFavoriteQuest)
|
||||||
|
dumpSaveData(s, pkt.Data, "favquest")
|
||||||
s.server.db.Exec("UPDATE characters SET savefavoritequest=$1 WHERE id=$2", pkt.Data, s.charID)
|
s.server.db.Exec("UPDATE characters SET savefavoritequest=$1 WHERE id=$2", pkt.Data, s.charID)
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package channelserver
|
|||||||
import (
|
import (
|
||||||
ps "erupe-ce/common/pascalstring"
|
ps "erupe-ce/common/pascalstring"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/jmoiron/sqlx"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
@@ -15,6 +16,7 @@ func handleMsgMhfSaveRengokuData(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
// saved every floor on road, holds values such as floors progressed, points etc.
|
// saved every floor on road, holds values such as floors progressed, points etc.
|
||||||
// can be safely handled by the client
|
// can be safely handled by the client
|
||||||
pkt := p.(*mhfpacket.MsgMhfSaveRengokuData)
|
pkt := p.(*mhfpacket.MsgMhfSaveRengokuData)
|
||||||
|
dumpSaveData(s, pkt.RawDataPayload, "rengoku")
|
||||||
_, err := s.server.db.Exec("UPDATE characters SET rengokudata=$1 WHERE id=$2", pkt.RawDataPayload, s.charID)
|
_, err := s.server.db.Exec("UPDATE characters SET rengokudata=$1 WHERE id=$2", pkt.RawDataPayload, s.charID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.logger.Fatal("Failed to update rengokudata savedata in db", zap.Error(err))
|
s.logger.Fatal("Failed to update rengokudata savedata in db", zap.Error(err))
|
||||||
@@ -95,20 +97,13 @@ func handleMsgMhfGetRengokuBinary(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
doAckBufSucceed(s, pkt.AckHandle, data)
|
doAckBufSucceed(s, pkt.AckHandle, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
const rengokuScoreQuery = `
|
const rengokuScoreQuery = `, c.name FROM rengoku_score rs
|
||||||
SELECT max_stages_mp, max_points_mp, max_stages_sp, max_points_sp, c.name, gc.guild_id
|
|
||||||
FROM rengoku_score rs
|
|
||||||
LEFT JOIN characters c ON c.id = rs.character_id
|
LEFT JOIN characters c ON c.id = rs.character_id
|
||||||
LEFT JOIN guild_characters gc ON gc.character_id = rs.character_id
|
LEFT JOIN guild_characters gc ON gc.character_id = rs.character_id `
|
||||||
`
|
|
||||||
|
|
||||||
type RengokuScore struct {
|
type RengokuScore struct {
|
||||||
Name string `db:"name"`
|
Name string `db:"name"`
|
||||||
GuildID int `db:"guild_id"`
|
Score uint32 `db:"score"`
|
||||||
MaxStagesMP uint32 `db:"max_stages_mp"`
|
|
||||||
MaxPointsMP uint32 `db:"max_points_mp"`
|
|
||||||
MaxStagesSP uint32 `db:"max_stages_sp"`
|
|
||||||
MaxPointsSP uint32 `db:"max_points_sp"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfEnumerateRengokuRanking(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfEnumerateRengokuRanking(s *Session, p mhfpacket.MHFPacket) {
|
||||||
@@ -120,155 +115,61 @@ func handleMsgMhfEnumerateRengokuRanking(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
guild = nil
|
guild = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if pkt.Leaderboard == 2 || pkt.Leaderboard == 3 || pkt.Leaderboard == 6 || pkt.Leaderboard == 7 {
|
||||||
|
if guild == nil {
|
||||||
|
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 11))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var score RengokuScore
|
var score RengokuScore
|
||||||
|
var selfExist bool
|
||||||
i := uint32(1)
|
i := uint32(1)
|
||||||
bf := byteframe.NewByteFrame()
|
bf := byteframe.NewByteFrame()
|
||||||
scoreData := byteframe.NewByteFrame()
|
scoreData := byteframe.NewByteFrame()
|
||||||
|
|
||||||
|
var rows *sqlx.Rows
|
||||||
switch pkt.Leaderboard {
|
switch pkt.Leaderboard {
|
||||||
case 0: // Max stage overall MP
|
case 0:
|
||||||
rows, _ := s.server.db.Queryx(fmt.Sprintf("%s ORDER BY max_stages_mp DESC", rengokuScoreQuery))
|
rows, _ = s.server.db.Queryx(fmt.Sprintf("SELECT max_stages_mp AS score %s ORDER BY max_stages_mp DESC", rengokuScoreQuery))
|
||||||
|
case 1:
|
||||||
|
rows, _ = s.server.db.Queryx(fmt.Sprintf("SELECT max_points_mp AS score %s ORDER BY max_points_mp DESC", rengokuScoreQuery))
|
||||||
|
case 2:
|
||||||
|
rows, _ = s.server.db.Queryx(fmt.Sprintf("SELECT max_stages_mp AS score %s WHERE guild_id=$1 ORDER BY max_stages_mp DESC", rengokuScoreQuery), guild.ID)
|
||||||
|
case 3:
|
||||||
|
rows, _ = s.server.db.Queryx(fmt.Sprintf("SELECT max_points_mp AS score %s WHERE guild_id=$1 ORDER BY max_points_mp DESC", rengokuScoreQuery), guild.ID)
|
||||||
|
case 4:
|
||||||
|
rows, _ = s.server.db.Queryx(fmt.Sprintf("SELECT max_stages_sp AS score %s ORDER BY max_stages_sp DESC", rengokuScoreQuery))
|
||||||
|
case 5:
|
||||||
|
rows, _ = s.server.db.Queryx(fmt.Sprintf("SELECT max_points_sp AS score %s ORDER BY max_points_sp DESC", rengokuScoreQuery))
|
||||||
|
case 6:
|
||||||
|
rows, _ = s.server.db.Queryx(fmt.Sprintf("SELECT max_stages_sp AS score %s WHERE guild_id=$1 ORDER BY max_stages_sp DESC", rengokuScoreQuery), guild.ID)
|
||||||
|
case 7:
|
||||||
|
rows, _ = s.server.db.Queryx(fmt.Sprintf("SELECT max_points_sp AS score %s WHERE guild_id=$1 ORDER BY max_points_sp DESC", rengokuScoreQuery), guild.ID)
|
||||||
|
}
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
rows.StructScan(&score)
|
rows.StructScan(&score)
|
||||||
if score.Name == s.Name {
|
if score.Name == s.Name {
|
||||||
bf.WriteUint32(i)
|
bf.WriteUint32(i)
|
||||||
bf.WriteUint32(score.MaxStagesMP)
|
bf.WriteUint32(score.Score)
|
||||||
ps.Uint8(bf, s.Name, true)
|
ps.Uint8(bf, s.Name, true)
|
||||||
ps.Uint8(bf, "", false)
|
ps.Uint8(bf, "", false)
|
||||||
|
selfExist = true
|
||||||
|
}
|
||||||
|
if i > 100 {
|
||||||
|
i++
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
scoreData.WriteUint32(i)
|
scoreData.WriteUint32(i)
|
||||||
scoreData.WriteUint32(score.MaxStagesMP)
|
scoreData.WriteUint32(score.Score)
|
||||||
ps.Uint8(scoreData, score.Name, true)
|
ps.Uint8(scoreData, score.Name, true)
|
||||||
ps.Uint8(scoreData, "", false)
|
ps.Uint8(scoreData, "", false)
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
case 1: // Max RdP overall MP
|
|
||||||
rows, _ := s.server.db.Queryx(fmt.Sprintf("%s ORDER BY max_points_mp DESC", rengokuScoreQuery))
|
if !selfExist {
|
||||||
for rows.Next() {
|
bf.WriteBytes(make([]byte, 10))
|
||||||
rows.StructScan(&score)
|
|
||||||
if score.Name == s.Name {
|
|
||||||
bf.WriteUint32(i)
|
|
||||||
bf.WriteUint32(score.MaxPointsMP)
|
|
||||||
ps.Uint8(bf, s.Name, true)
|
|
||||||
ps.Uint8(bf, "", false)
|
|
||||||
}
|
|
||||||
scoreData.WriteUint32(i)
|
|
||||||
scoreData.WriteUint32(score.MaxPointsMP)
|
|
||||||
ps.Uint8(scoreData, score.Name, true)
|
|
||||||
ps.Uint8(scoreData, "", false)
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
case 2: // Max stage guild MP
|
|
||||||
if guild != nil {
|
|
||||||
rows, _ := s.server.db.Queryx(fmt.Sprintf("%s WHERE guild_id=$1 ORDER BY max_stages_mp DESC", rengokuScoreQuery), guild.ID)
|
|
||||||
for rows.Next() {
|
|
||||||
rows.StructScan(&score)
|
|
||||||
if score.Name == s.Name {
|
|
||||||
bf.WriteUint32(i)
|
|
||||||
bf.WriteUint32(score.MaxStagesMP)
|
|
||||||
ps.Uint8(bf, s.Name, true)
|
|
||||||
ps.Uint8(bf, "", false)
|
|
||||||
}
|
|
||||||
scoreData.WriteUint32(i)
|
|
||||||
scoreData.WriteUint32(score.MaxStagesMP)
|
|
||||||
ps.Uint8(scoreData, score.Name, true)
|
|
||||||
ps.Uint8(scoreData, "", false)
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bf.WriteBytes(make([]byte, 11))
|
|
||||||
}
|
|
||||||
case 3: // Max RdP guild MP
|
|
||||||
if guild != nil {
|
|
||||||
rows, _ := s.server.db.Queryx(fmt.Sprintf("%s WHERE guild_id=$1 ORDER BY max_points_mp DESC", rengokuScoreQuery), guild.ID)
|
|
||||||
for rows.Next() {
|
|
||||||
rows.StructScan(&score)
|
|
||||||
if score.Name == s.Name {
|
|
||||||
bf.WriteUint32(i)
|
|
||||||
bf.WriteUint32(score.MaxPointsMP)
|
|
||||||
ps.Uint8(bf, s.Name, true)
|
|
||||||
ps.Uint8(bf, "", false)
|
|
||||||
}
|
|
||||||
scoreData.WriteUint32(i)
|
|
||||||
scoreData.WriteUint32(score.MaxPointsMP)
|
|
||||||
ps.Uint8(scoreData, score.Name, true)
|
|
||||||
ps.Uint8(scoreData, "", false)
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bf.WriteBytes(make([]byte, 11))
|
|
||||||
}
|
|
||||||
case 4: // Max stage overall SP
|
|
||||||
rows, _ := s.server.db.Queryx(fmt.Sprintf("%s ORDER BY max_stages_sp DESC", rengokuScoreQuery))
|
|
||||||
for rows.Next() {
|
|
||||||
rows.StructScan(&score)
|
|
||||||
if score.Name == s.Name {
|
|
||||||
bf.WriteUint32(i)
|
|
||||||
bf.WriteUint32(score.MaxStagesSP)
|
|
||||||
ps.Uint8(bf, s.Name, true)
|
|
||||||
ps.Uint8(bf, "", false)
|
|
||||||
}
|
|
||||||
scoreData.WriteUint32(i)
|
|
||||||
scoreData.WriteUint32(score.MaxStagesSP)
|
|
||||||
ps.Uint8(scoreData, score.Name, true)
|
|
||||||
ps.Uint8(scoreData, "", false)
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
case 5: // Max RdP overall SP
|
|
||||||
rows, _ := s.server.db.Queryx(fmt.Sprintf("%s ORDER BY max_points_sp DESC", rengokuScoreQuery))
|
|
||||||
for rows.Next() {
|
|
||||||
rows.StructScan(&score)
|
|
||||||
if score.Name == s.Name {
|
|
||||||
bf.WriteUint32(i)
|
|
||||||
bf.WriteUint32(score.MaxPointsSP)
|
|
||||||
ps.Uint8(bf, s.Name, true)
|
|
||||||
ps.Uint8(bf, "", false)
|
|
||||||
}
|
|
||||||
scoreData.WriteUint32(i)
|
|
||||||
scoreData.WriteUint32(score.MaxPointsSP)
|
|
||||||
ps.Uint8(scoreData, score.Name, true)
|
|
||||||
ps.Uint8(scoreData, "", false)
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
case 6: // Max stage guild SP
|
|
||||||
if guild != nil {
|
|
||||||
rows, _ := s.server.db.Queryx(fmt.Sprintf("%s WHERE guild_id=$1 ORDER BY max_stages_sp DESC", rengokuScoreQuery), guild.ID)
|
|
||||||
for rows.Next() {
|
|
||||||
rows.StructScan(&score)
|
|
||||||
if score.Name == s.Name {
|
|
||||||
bf.WriteUint32(i)
|
|
||||||
bf.WriteUint32(score.MaxStagesSP)
|
|
||||||
ps.Uint8(bf, s.Name, true)
|
|
||||||
ps.Uint8(bf, "", false)
|
|
||||||
}
|
|
||||||
scoreData.WriteUint32(i)
|
|
||||||
scoreData.WriteUint32(score.MaxStagesSP)
|
|
||||||
ps.Uint8(scoreData, score.Name, true)
|
|
||||||
ps.Uint8(scoreData, "", false)
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bf.WriteBytes(make([]byte, 11))
|
|
||||||
}
|
|
||||||
case 7: // Max RdP guild SP
|
|
||||||
if guild != nil {
|
|
||||||
rows, _ := s.server.db.Queryx(fmt.Sprintf("%s WHERE guild_id=$1 ORDER BY max_points_sp DESC", rengokuScoreQuery), guild.ID)
|
|
||||||
for rows.Next() {
|
|
||||||
rows.StructScan(&score)
|
|
||||||
if score.Name == s.Name {
|
|
||||||
bf.WriteUint32(i)
|
|
||||||
bf.WriteUint32(score.MaxPointsSP)
|
|
||||||
ps.Uint8(bf, s.Name, true)
|
|
||||||
ps.Uint8(bf, "", false)
|
|
||||||
}
|
|
||||||
scoreData.WriteUint32(i)
|
|
||||||
scoreData.WriteUint32(score.MaxPointsSP)
|
|
||||||
ps.Uint8(scoreData, score.Name, true)
|
|
||||||
ps.Uint8(scoreData, "", false)
|
|
||||||
i++
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
bf.WriteBytes(make([]byte, 11))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
bf.WriteUint8(uint8(i) - 1)
|
bf.WriteUint8(uint8(i) - 1)
|
||||||
bf.WriteBytes(scoreData.Data())
|
bf.WriteBytes(scoreData.Data())
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ func handleMsgSysCreateStage(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
doAckSimpleFail(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
doAckSimpleFail(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
||||||
} else {
|
} else {
|
||||||
stage := NewStage(pkt.StageID)
|
stage := NewStage(pkt.StageID)
|
||||||
|
stage.host = s
|
||||||
stage.maxPlayers = uint16(pkt.PlayerCount)
|
stage.maxPlayers = uint16(pkt.PlayerCount)
|
||||||
s.server.stages[stage.id] = stage
|
s.server.stages[stage.id] = stage
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
||||||
@@ -42,6 +43,7 @@ func doStageTransfer(s *Session, ackHandle uint32, stageID string) {
|
|||||||
stage = s.server.stages[stageID]
|
stage = s.server.stages[stageID]
|
||||||
s.server.Unlock()
|
s.server.Unlock()
|
||||||
stage.Lock()
|
stage.Lock()
|
||||||
|
stage.host = s
|
||||||
stage.clients[s] = s.charID
|
stage.clients[s] = s.charID
|
||||||
stage.Unlock()
|
stage.Unlock()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ func handleMsgMhfGetTowerInfo(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
type:
|
type:
|
||||||
1 == TOWER_RANK_POINT,
|
1 == TOWER_RANK_POINT,
|
||||||
2 == GET_OWN_TOWER_SKILL
|
2 == GET_OWN_TOWER_SKILL
|
||||||
3 == ?
|
3 == GET_OWN_TOWER_LEVEL_V3
|
||||||
4 == TOWER_TOUHA_HISTORY
|
4 == TOWER_TOUHA_HISTORY
|
||||||
5 = ?
|
5 = ?
|
||||||
|
|
||||||
@@ -39,8 +39,8 @@ func handleMsgMhfGetTowerInfo(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
case mhfpacket.TowerInfoTypeGetOwnTowerSkill:
|
case mhfpacket.TowerInfoTypeGetOwnTowerSkill:
|
||||||
//data, err = hex.DecodeString("0A218EAD000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
|
//data, err = hex.DecodeString("0A218EAD000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
|
||||||
data, err = hex.DecodeString("0A218EAD0000000000000000000000010000001C0000000500050000000000020000000000000000000000000000000000030003000000000003000500050000000300030003000300030003000200030001000300020002000300010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
|
data, err = hex.DecodeString("0A218EAD0000000000000000000000010000001C0000000500050000000000020000000000000000000000000000000000030003000000000003000500050000000300030003000300030003000200030001000300020002000300010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
|
||||||
case mhfpacket.TowerInfoTypeUnk3:
|
case mhfpacket.TowerInfoTypeGetOwnTowerLevelV3:
|
||||||
panic("No known response values for TowerInfoTypeUnk3")
|
panic("No known response values for GetOwnTowerLevelV3")
|
||||||
case mhfpacket.TowerInfoTypeTowerTouhaHistory:
|
case mhfpacket.TowerInfoTypeTowerTouhaHistory:
|
||||||
data, err = hex.DecodeString("0A218EAD0000000000000000000000010000000000000000000000000000000000000000")
|
data, err = hex.DecodeString("0A218EAD0000000000000000000000010000000000000000000000000000000000000000")
|
||||||
case mhfpacket.TowerInfoTypeUnk5:
|
case mhfpacket.TowerInfoTypeUnk5:
|
||||||
@@ -58,6 +58,9 @@ func handleMsgMhfPostTowerInfo(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfGetGemInfo(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgMhfGetGemInfo(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
pkt := p.(*mhfpacket.MsgMhfGetGemInfo)
|
||||||
|
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 8))
|
||||||
|
}
|
||||||
|
|
||||||
func handleMsgMhfPostGemInfo(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgMhfPostGemInfo(s *Session, p mhfpacket.MHFPacket) {}
|
||||||
|
|||||||
@@ -17,12 +17,12 @@ func handleMsgSysSetUserBinary(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
s.server.userBinaryPartsLock.Unlock()
|
s.server.userBinaryPartsLock.Unlock()
|
||||||
|
|
||||||
var exists []byte
|
var exists []byte
|
||||||
err := s.server.db.QueryRow("SELECT type2 FROM user_binaries WHERE id=$1", s.charID).Scan(&exists)
|
err := s.server.db.QueryRow("SELECT type2 FROM user_binary WHERE id=$1", s.charID).Scan(&exists)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.server.db.Exec("INSERT INTO user_binaries (id) VALUES ($1)", s.charID)
|
s.server.db.Exec("INSERT INTO user_binary (id) VALUES ($1)", s.charID)
|
||||||
}
|
}
|
||||||
|
|
||||||
s.server.db.Exec(fmt.Sprintf("UPDATE user_binaries SET type%d=$1 WHERE id=$2", pkt.BinaryType), pkt.RawDataPayload, s.charID)
|
s.server.db.Exec(fmt.Sprintf("UPDATE user_binary SET type%d=$1 WHERE id=$2", pkt.BinaryType), pkt.RawDataPayload, s.charID)
|
||||||
|
|
||||||
msg := &mhfpacket.MsgSysNotifyUserBinary{
|
msg := &mhfpacket.MsgSysNotifyUserBinary{
|
||||||
CharID: s.charID,
|
CharID: s.charID,
|
||||||
@@ -42,7 +42,7 @@ func handleMsgSysGetUserBinary(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
|
|
||||||
// If we can't get the real data, try to get it from the database.
|
// If we can't get the real data, try to get it from the database.
|
||||||
if !ok {
|
if !ok {
|
||||||
err := s.server.db.QueryRow(fmt.Sprintf("SELECT type%d FROM user_binaries WHERE id=$1", pkt.BinaryType), pkt.CharID).Scan(&data)
|
err := s.server.db.QueryRow(fmt.Sprintf("SELECT type%d FROM user_binary WHERE id=$1", pkt.BinaryType), pkt.CharID).Scan(&data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
|
doAckBufFail(s, pkt.AckHandle, make([]byte, 4))
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,22 +1,28 @@
|
|||||||
package channelserver
|
package channelserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/binary"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
"erupe-ce/common/stringstack"
|
"erupe-ce/common/stringstack"
|
||||||
"erupe-ce/common/stringsupport"
|
|
||||||
"erupe-ce/network"
|
"erupe-ce/network"
|
||||||
"erupe-ce/network/clientctx"
|
"erupe-ce/network/clientctx"
|
||||||
"erupe-ce/network/mhfpacket"
|
"erupe-ce/network/mhfpacket"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"golang.org/x/text/encoding/japanese"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type packet struct {
|
||||||
|
data []byte
|
||||||
|
nonBlocking bool
|
||||||
|
}
|
||||||
|
|
||||||
// Session holds state for the channel server connection.
|
// Session holds state for the channel server connection.
|
||||||
type Session struct {
|
type Session struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
@@ -24,11 +30,10 @@ type Session struct {
|
|||||||
server *Server
|
server *Server
|
||||||
rawConn net.Conn
|
rawConn net.Conn
|
||||||
cryptConn *network.CryptConn
|
cryptConn *network.CryptConn
|
||||||
sendPackets chan []byte
|
sendPackets chan packet
|
||||||
clientContext *clientctx.ClientContext
|
clientContext *clientctx.ClientContext
|
||||||
|
|
||||||
userEnteredStage bool // If the user has entered a stage before
|
userEnteredStage bool // If the user has entered a stage before
|
||||||
myseries MySeries
|
|
||||||
stageID string
|
stageID string
|
||||||
stage *Stage
|
stage *Stage
|
||||||
reservationStage *Stage // Required for the stateful MsgSysUnreserveStage packet.
|
reservationStage *Stage // Required for the stateful MsgSysUnreserveStage packet.
|
||||||
@@ -37,8 +42,10 @@ type Session struct {
|
|||||||
charID uint32
|
charID uint32
|
||||||
logKey []byte
|
logKey []byte
|
||||||
sessionStart int64
|
sessionStart int64
|
||||||
rights uint32
|
courses []mhfpacket.Course
|
||||||
token string
|
token string
|
||||||
|
kqf []byte
|
||||||
|
kqfOverride bool
|
||||||
|
|
||||||
semaphore *Semaphore // Required for the stateful MsgSysUnreserveStage packet.
|
semaphore *Semaphore // Required for the stateful MsgSysUnreserveStage packet.
|
||||||
|
|
||||||
@@ -54,17 +61,7 @@ type Session struct {
|
|||||||
|
|
||||||
// For Debuging
|
// For Debuging
|
||||||
Name string
|
Name string
|
||||||
}
|
closed bool
|
||||||
|
|
||||||
type MySeries struct {
|
|
||||||
houseTier []byte
|
|
||||||
houseData []byte
|
|
||||||
bookshelfData []byte
|
|
||||||
galleryData []byte
|
|
||||||
toreData []byte
|
|
||||||
gardenData []byte
|
|
||||||
state uint8
|
|
||||||
password string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSession creates a new Session type.
|
// NewSession creates a new Session type.
|
||||||
@@ -74,13 +71,8 @@ func NewSession(server *Server, conn net.Conn) *Session {
|
|||||||
server: server,
|
server: server,
|
||||||
rawConn: conn,
|
rawConn: conn,
|
||||||
cryptConn: network.NewCryptConn(conn),
|
cryptConn: network.NewCryptConn(conn),
|
||||||
sendPackets: make(chan []byte, 20),
|
sendPackets: make(chan packet, 20),
|
||||||
clientContext: &clientctx.ClientContext{
|
clientContext: &clientctx.ClientContext{}, // Unused
|
||||||
StrConv: &stringsupport.StringConverter{
|
|
||||||
Encoding: japanese.ShiftJIS,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
userEnteredStage: false,
|
|
||||||
sessionStart: Time_Current_Adjusted().Unix(),
|
sessionStart: Time_Current_Adjusted().Unix(),
|
||||||
stageMoveStack: stringstack.New(),
|
stageMoveStack: stringstack.New(),
|
||||||
}
|
}
|
||||||
@@ -100,19 +92,34 @@ func (s *Session) Start() {
|
|||||||
|
|
||||||
// QueueSend queues a packet (raw []byte) to be sent.
|
// QueueSend queues a packet (raw []byte) to be sent.
|
||||||
func (s *Session) QueueSend(data []byte) {
|
func (s *Session) QueueSend(data []byte) {
|
||||||
bf := byteframe.NewByteFrameFromBytes(data[:2])
|
s.logMessage(binary.BigEndian.Uint16(data[0:2]), data, "Server", s.Name)
|
||||||
s.logMessage(bf.ReadUint16(), data, "Server", s.Name)
|
select {
|
||||||
s.sendPackets <- data
|
case s.sendPackets <- packet{data, false}:
|
||||||
|
// Enqueued data
|
||||||
|
default:
|
||||||
|
s.logger.Warn("Packet queue too full, flushing!")
|
||||||
|
var tempPackets []packet
|
||||||
|
for len(s.sendPackets) > 0 {
|
||||||
|
tempPacket := <-s.sendPackets
|
||||||
|
if !tempPacket.nonBlocking {
|
||||||
|
tempPackets = append(tempPackets, tempPacket)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, tempPacket := range tempPackets {
|
||||||
|
s.sendPackets <- tempPacket
|
||||||
|
}
|
||||||
|
s.sendPackets <- packet{data, false}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueueSendNonBlocking queues a packet (raw []byte) to be sent, dropping the packet entirely if the queue is full.
|
// QueueSendNonBlocking queues a packet (raw []byte) to be sent, dropping the packet entirely if the queue is full.
|
||||||
func (s *Session) QueueSendNonBlocking(data []byte) {
|
func (s *Session) QueueSendNonBlocking(data []byte) {
|
||||||
select {
|
select {
|
||||||
case s.sendPackets <- data:
|
case s.sendPackets <- packet{data, true}:
|
||||||
// Enqueued properly.
|
// Enqueued data
|
||||||
default:
|
default:
|
||||||
// Couldn't enqueue, likely something wrong with the connection.
|
s.logger.Warn("Packet queue too full, dropping!")
|
||||||
s.logger.Warn("Dropped packet for session because of full send buffer, something is probably wrong")
|
// Queue too full
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,29 +147,25 @@ func (s *Session) QueueAck(ackHandle uint32, data []byte) {
|
|||||||
|
|
||||||
func (s *Session) sendLoop() {
|
func (s *Session) sendLoop() {
|
||||||
for {
|
for {
|
||||||
// TODO(Andoryuuta): Test making this into a buffered channel and grouping the packet together before sending.
|
if s.closed {
|
||||||
rawPacket := <-s.sendPackets
|
|
||||||
|
|
||||||
if rawPacket == nil {
|
|
||||||
s.logger.Debug("Got nil from s.SendPackets, exiting send loop")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
pkt := <-s.sendPackets
|
||||||
// Make a copy of the data.
|
err := s.cryptConn.SendPacket(append(pkt.data, []byte{0x00, 0x10}...))
|
||||||
terminatedPacket := make([]byte, len(rawPacket))
|
if err != nil {
|
||||||
copy(terminatedPacket, rawPacket)
|
s.logger.Warn("Failed to send packet")
|
||||||
|
}
|
||||||
// Append the MSG_SYS_END tailing opcode.
|
time.Sleep(10 * time.Millisecond)
|
||||||
terminatedPacket = append(terminatedPacket, []byte{0x00, 0x10}...)
|
|
||||||
|
|
||||||
s.cryptConn.SendPacket(terminatedPacket)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) recvLoop() {
|
func (s *Session) recvLoop() {
|
||||||
for {
|
for {
|
||||||
|
if s.closed {
|
||||||
|
logoutPlayer(s)
|
||||||
|
return
|
||||||
|
}
|
||||||
pkt, err := s.cryptConn.ReadPacket()
|
pkt, err := s.cryptConn.ReadPacket()
|
||||||
|
|
||||||
if err == io.EOF {
|
if err == io.EOF {
|
||||||
s.logger.Info(fmt.Sprintf("[%s] Disconnected", s.Name))
|
s.logger.Info(fmt.Sprintf("[%s] Disconnected", s.Name))
|
||||||
logoutPlayer(s)
|
logoutPlayer(s)
|
||||||
@@ -174,6 +177,7 @@ func (s *Session) recvLoop() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
s.handlePacketGroup(pkt)
|
s.handlePacketGroup(pkt)
|
||||||
|
time.Sleep(10 * time.Millisecond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -193,7 +197,8 @@ func (s *Session) handlePacketGroup(pktGroup []byte) {
|
|||||||
s.logMessage(opcodeUint16, pktGroup, s.Name, "Server")
|
s.logMessage(opcodeUint16, pktGroup, s.Name, "Server")
|
||||||
|
|
||||||
if opcode == network.MSG_SYS_LOGOUT {
|
if opcode == network.MSG_SYS_LOGOUT {
|
||||||
s.rawConn.Close()
|
s.closed = true
|
||||||
|
return
|
||||||
}
|
}
|
||||||
// Get the packet parser and handler for this opcode.
|
// Get the packet parser and handler for this opcode.
|
||||||
mhfPkt := mhfpacket.FromOpcode(opcode)
|
mhfPkt := mhfpacket.FromOpcode(opcode)
|
||||||
@@ -258,3 +263,14 @@ func (s *Session) logMessage(opcode uint16, data []byte, sender string, recipien
|
|||||||
fmt.Printf("Data [%d bytes]:\n(Too long!)\n\n", len(data))
|
fmt.Printf("Data [%d bytes]:\n(Too long!)\n\n", len(data))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Session) FindCourse(name string) mhfpacket.Course {
|
||||||
|
for _, course := range s.courses {
|
||||||
|
for _, alias := range course.Aliases {
|
||||||
|
if strings.ToLower(name) == strings.ToLower(alias) {
|
||||||
|
return course
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mhfpacket.Course{}
|
||||||
|
}
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ type Stage struct {
|
|||||||
// other clients expect the server to echo them back in the exact same format.
|
// other clients expect the server to echo them back in the exact same format.
|
||||||
rawBinaryData map[stageBinaryKey][]byte
|
rawBinaryData map[stageBinaryKey][]byte
|
||||||
|
|
||||||
|
host *Session
|
||||||
maxPlayers uint16
|
maxPlayers uint16
|
||||||
password string
|
password string
|
||||||
createdAt string
|
createdAt string
|
||||||
|
|||||||
@@ -90,6 +90,7 @@ func (s *Server) acceptClients() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) handleEntranceServerConnection(conn net.Conn) {
|
func (s *Server) handleEntranceServerConnection(conn net.Conn) {
|
||||||
|
defer conn.Close()
|
||||||
// Client initalizes the connection with a one-time buffer of 8 NULL bytes.
|
// Client initalizes the connection with a one-time buffer of 8 NULL bytes.
|
||||||
nullInit := make([]byte, 8)
|
nullInit := make([]byte, 8)
|
||||||
n, err := io.ReadFull(conn, nullInit)
|
n, err := io.ReadFull(conn, nullInit)
|
||||||
@@ -118,5 +119,4 @@ func (s *Server) handleEntranceServerConnection(conn net.Conn) {
|
|||||||
cc.SendPacket(data)
|
cc.SendPacket(data)
|
||||||
// Close because we only need to send the response once.
|
// Close because we only need to send the response once.
|
||||||
// Any further requests from the client will come from a new connection.
|
// Any further requests from the client will come from a new connection.
|
||||||
conn.Close()
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ func encodeServerInfo(config *config.Config, s *Server) []byte {
|
|||||||
sid := (4096 + serverIdx*256) + 16
|
sid := (4096 + serverIdx*256) + 16
|
||||||
err := s.db.QueryRow("SELECT season FROM servers WHERE server_id=$1", sid).Scan(&season)
|
err := s.db.QueryRow("SELECT season FROM servers WHERE server_id=$1", sid).Scan(&season)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
season = 0
|
||||||
}
|
}
|
||||||
if si.IP == "" {
|
if si.IP == "" {
|
||||||
si.IP = config.Host
|
si.IP = config.Host
|
||||||
@@ -50,7 +50,7 @@ func encodeServerInfo(config *config.Config, s *Server) []byte {
|
|||||||
bf.WriteUint16(ci.MaxPlayers)
|
bf.WriteUint16(ci.MaxPlayers)
|
||||||
err := s.db.QueryRow("SELECT current_players FROM servers WHERE server_id=$1", sid).Scan(¤tplayers)
|
err := s.db.QueryRow("SELECT current_players FROM servers WHERE server_id=$1", sid).Scan(¤tplayers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
currentplayers = 0
|
||||||
}
|
}
|
||||||
bf.WriteUint16(currentplayers)
|
bf.WriteUint16(currentplayers)
|
||||||
bf.WriteUint32(0)
|
bf.WriteUint32(0)
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ func (s *Server) registerDBAccount(username string, password string) error {
|
|||||||
INSERT INTO characters (
|
INSERT INTO characters (
|
||||||
user_id, is_female, is_new_character, name, unk_desc_string,
|
user_id, is_female, is_new_character, name, unk_desc_string,
|
||||||
hrp, gr, weapon_type, last_login)
|
hrp, gr, weapon_type, last_login)
|
||||||
VALUES($1, False, True, '', '', 1, 0, 0, $2)`,
|
VALUES($1, False, True, '', '', 0, 0, 0, $2)`,
|
||||||
id,
|
id,
|
||||||
uint32(time.Now().Unix()),
|
uint32(time.Now().Unix()),
|
||||||
)
|
)
|
||||||
@@ -148,7 +148,7 @@ func (s *Server) getFriendsForCharacters(chars []character) []members {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for i, _ := range charFriends {
|
for i := range charFriends {
|
||||||
charFriends[i].CID = char.ID
|
charFriends[i].CID = char.ID
|
||||||
}
|
}
|
||||||
friends = append(friends, charFriends...)
|
friends = append(friends, charFriends...)
|
||||||
|
|||||||
@@ -43,12 +43,22 @@ func (s *Session) makeSignInResp(uid int) []byte {
|
|||||||
bf := byteframe.NewByteFrame()
|
bf := byteframe.NewByteFrame()
|
||||||
|
|
||||||
bf.WriteUint8(1) // resp_code
|
bf.WriteUint8(1) // resp_code
|
||||||
bf.WriteUint8(0) // file/patch server count
|
if s.server.erupeConfig.DevMode && s.server.erupeConfig.DevModeOptions.PatchServerManifest != "" && s.server.erupeConfig.DevModeOptions.PatchServerFile != "" {
|
||||||
|
bf.WriteUint8(2)
|
||||||
|
} else {
|
||||||
|
bf.WriteUint8(0)
|
||||||
|
}
|
||||||
bf.WriteUint8(1) // entrance server count
|
bf.WriteUint8(1) // entrance server count
|
||||||
bf.WriteUint8(uint8(len(chars))) // character count
|
bf.WriteUint8(uint8(len(chars))) // character count
|
||||||
bf.WriteUint32(0xFFFFFFFF) // login_token_number
|
bf.WriteUint32(0xFFFFFFFF) // login_token_number
|
||||||
bf.WriteBytes([]byte(token)) // login_token
|
bf.WriteBytes([]byte(token)) // login_token
|
||||||
bf.WriteUint32(uint32(time.Now().Unix())) // current time
|
bf.WriteUint32(uint32(time.Now().Unix())) // current time
|
||||||
|
if s.server.erupeConfig.DevMode {
|
||||||
|
if s.server.erupeConfig.DevModeOptions.PatchServerManifest != "" && s.server.erupeConfig.DevModeOptions.PatchServerFile != "" {
|
||||||
|
ps.Uint8(bf, s.server.erupeConfig.DevModeOptions.PatchServerManifest, false)
|
||||||
|
ps.Uint8(bf, s.server.erupeConfig.DevModeOptions.PatchServerFile, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
ps.Uint8(bf, fmt.Sprintf("%s:%d", s.server.erupeConfig.Host, s.server.erupeConfig.Entrance.Port), false)
|
ps.Uint8(bf, fmt.Sprintf("%s:%d", s.server.erupeConfig.Host, s.server.erupeConfig.Entrance.Port), false)
|
||||||
|
|
||||||
lastPlayed := uint32(0)
|
lastPlayed := uint32(0)
|
||||||
@@ -112,14 +122,22 @@ func (s *Session) makeSignInResp(uid int) []byte {
|
|||||||
bf.WriteUint32(s.server.getLastCID(uid))
|
bf.WriteUint32(s.server.getLastCID(uid))
|
||||||
bf.WriteUint32(s.server.getUserRights(uid))
|
bf.WriteUint32(s.server.getUserRights(uid))
|
||||||
ps.Uint16(bf, "", false) // filters
|
ps.Uint16(bf, "", false) // filters
|
||||||
bf.WriteUint32(0xCA104E20)
|
bf.WriteUint16(0xCA10)
|
||||||
ps.Uint16(bf, "", false) // encryption
|
bf.WriteUint16(0x4E20)
|
||||||
|
ps.Uint16(bf, "", false) // unk key
|
||||||
bf.WriteUint8(0x00)
|
bf.WriteUint8(0x00)
|
||||||
bf.WriteUint32(0xCA110001)
|
bf.WriteUint16(0xCA11)
|
||||||
bf.WriteUint32(0x4E200000)
|
bf.WriteUint16(0x0001)
|
||||||
|
bf.WriteUint16(0x4E20)
|
||||||
|
ps.Uint16(bf, "", false) // unk ipv4
|
||||||
|
if returnExpiry.Before(time.Now()) {
|
||||||
|
// Hack to make Return work while having a non-adjusted expiry
|
||||||
|
bf.WriteUint32(0)
|
||||||
|
} else {
|
||||||
bf.WriteUint32(uint32(returnExpiry.Unix()))
|
bf.WriteUint32(uint32(returnExpiry.Unix()))
|
||||||
|
}
|
||||||
bf.WriteUint32(0x00000000)
|
bf.WriteUint32(0x00000000)
|
||||||
bf.WriteUint32(0x0A5197DF)
|
bf.WriteUint32(0x0A5197DF) // unk id
|
||||||
|
|
||||||
mezfes := s.server.erupeConfig.DevModeOptions.MezFesEvent
|
mezfes := s.server.erupeConfig.DevModeOptions.MezFesEvent
|
||||||
alt := s.server.erupeConfig.DevModeOptions.MezFesAlt
|
alt := s.server.erupeConfig.DevModeOptions.MezFesAlt
|
||||||
|
|||||||
@@ -16,33 +16,20 @@ import (
|
|||||||
type Session struct {
|
type Session struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
sid int
|
|
||||||
server *Server
|
server *Server
|
||||||
rawConn *net.Conn
|
rawConn net.Conn
|
||||||
cryptConn *network.CryptConn
|
cryptConn *network.CryptConn
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) fail() {
|
|
||||||
s.server.Lock()
|
|
||||||
delete(s.server.sessions, s.sid)
|
|
||||||
s.server.Unlock()
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Session) work() {
|
func (s *Session) work() {
|
||||||
for {
|
|
||||||
pkt, err := s.cryptConn.ReadPacket()
|
pkt, err := s.cryptConn.ReadPacket()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.fail()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.handlePacket(pkt)
|
err = s.handlePacket(pkt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.fail()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Session) handlePacket(pkt []byte) error {
|
func (s *Session) handlePacket(pkt []byte) error {
|
||||||
@@ -61,6 +48,7 @@ func (s *Session) handlePacket(pkt []byte) error {
|
|||||||
case "DELETE:100":
|
case "DELETE:100":
|
||||||
loginTokenString := string(bf.ReadNullTerminatedBytes())
|
loginTokenString := string(bf.ReadNullTerminatedBytes())
|
||||||
characterID := int(bf.ReadUint32())
|
characterID := int(bf.ReadUint32())
|
||||||
|
_ = int(bf.ReadUint32()) // login_token_number
|
||||||
s.server.deleteCharacter(characterID, loginTokenString)
|
s.server.deleteCharacter(characterID, loginTokenString)
|
||||||
sugar.Infof("Deleted character ID: %v\n", characterID)
|
sugar.Infof("Deleted character ID: %v\n", characterID)
|
||||||
err := s.cryptConn.SendPacket([]byte{0x01}) // DEL_SUCCESS
|
err := s.cryptConn.SendPacket([]byte{0x01}) // DEL_SUCCESS
|
||||||
@@ -78,13 +66,13 @@ func (s *Session) handleDSGNRequest(bf *byteframe.ByteFrame) error {
|
|||||||
|
|
||||||
reqUsername := string(bf.ReadNullTerminatedBytes())
|
reqUsername := string(bf.ReadNullTerminatedBytes())
|
||||||
reqPassword := string(bf.ReadNullTerminatedBytes())
|
reqPassword := string(bf.ReadNullTerminatedBytes())
|
||||||
reqUnk := string(bf.ReadNullTerminatedBytes())
|
reqSkey := string(bf.ReadNullTerminatedBytes())
|
||||||
|
|
||||||
s.server.logger.Info(
|
s.server.logger.Info(
|
||||||
"Got sign in request",
|
"Got sign in request",
|
||||||
zap.String("reqUsername", reqUsername),
|
zap.String("reqUsername", reqUsername),
|
||||||
zap.String("reqPassword", reqPassword),
|
zap.String("reqPassword", reqPassword),
|
||||||
zap.String("reqUnk", reqUnk),
|
zap.String("reqSkey", reqSkey),
|
||||||
)
|
)
|
||||||
|
|
||||||
newCharaReq := false
|
newCharaReq := false
|
||||||
@@ -105,7 +93,7 @@ func (s *Session) handleDSGNRequest(bf *byteframe.ByteFrame) error {
|
|||||||
s.logger.Info("Account not found", zap.String("reqUsername", reqUsername))
|
s.logger.Info("Account not found", zap.String("reqUsername", reqUsername))
|
||||||
serverRespBytes = makeSignInFailureResp(SIGN_EAUTH)
|
serverRespBytes = makeSignInFailureResp(SIGN_EAUTH)
|
||||||
|
|
||||||
// HACK(Andoryuuta): Create a new account if it doesn't exit.
|
if s.server.erupeConfig.DevMode && s.server.erupeConfig.DevModeOptions.AutoCreateAccount {
|
||||||
s.logger.Info("Creating account", zap.String("reqUsername", reqUsername), zap.String("reqPassword", reqPassword))
|
s.logger.Info("Creating account", zap.String("reqUsername", reqUsername), zap.String("reqPassword", reqPassword))
|
||||||
err = s.server.registerDBAccount(reqUsername, reqPassword)
|
err = s.server.registerDBAccount(reqUsername, reqPassword)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -113,6 +101,9 @@ func (s *Session) handleDSGNRequest(bf *byteframe.ByteFrame) error {
|
|||||||
serverRespBytes = makeSignInFailureResp(SIGN_EABORT)
|
serverRespBytes = makeSignInFailureResp(SIGN_EABORT)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
var id int
|
var id int
|
||||||
err = s.server.db.QueryRow("SELECT id FROM users WHERE username = $1", reqUsername).Scan(&id)
|
err = s.server.db.QueryRow("SELECT id FROM users WHERE username = $1", reqUsername).Scan(&id)
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ type Server struct {
|
|||||||
sync.Mutex
|
sync.Mutex
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
erupeConfig *config.Config
|
erupeConfig *config.Config
|
||||||
sid int
|
|
||||||
sessions map[int]*Session
|
sessions map[int]*Session
|
||||||
db *sqlx.DB
|
db *sqlx.DB
|
||||||
listener net.Listener
|
listener net.Listener
|
||||||
@@ -36,8 +35,6 @@ func NewServer(config *Config) *Server {
|
|||||||
s := &Server{
|
s := &Server{
|
||||||
logger: config.Logger,
|
logger: config.Logger,
|
||||||
erupeConfig: config.ErupeConfig,
|
erupeConfig: config.ErupeConfig,
|
||||||
sid: 0,
|
|
||||||
sessions: make(map[int]*Session),
|
|
||||||
db: config.DB,
|
db: config.DB,
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
@@ -84,20 +81,19 @@ func (s *Server) acceptClients() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
go s.handleConnection(s.sid, conn)
|
go s.handleConnection(conn)
|
||||||
s.sid++
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) handleConnection(sid int, conn net.Conn) {
|
func (s *Server) handleConnection(conn net.Conn) {
|
||||||
s.logger.Info("Got connection to sign server", zap.String("remoteaddr", conn.RemoteAddr().String()))
|
s.logger.Info("Got connection to sign server", zap.String("remoteaddr", conn.RemoteAddr().String()))
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
// Client initalizes the connection with a one-time buffer of 8 NULL bytes.
|
// Client initalizes the connection with a one-time buffer of 8 NULL bytes.
|
||||||
nullInit := make([]byte, 8)
|
nullInit := make([]byte, 8)
|
||||||
_, err := io.ReadFull(conn, nullInit)
|
_, err := io.ReadFull(conn, nullInit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
s.logger.Error("Error initialising sign server connection", zap.Error(err))
|
||||||
conn.Close()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,15 +101,10 @@ func (s *Server) handleConnection(sid int, conn net.Conn) {
|
|||||||
session := &Session{
|
session := &Session{
|
||||||
logger: s.logger,
|
logger: s.logger,
|
||||||
server: s,
|
server: s,
|
||||||
rawConn: &conn,
|
rawConn: conn,
|
||||||
cryptConn: network.NewCryptConn(conn),
|
cryptConn: network.NewCryptConn(conn),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the session to the server's sessions map.
|
|
||||||
s.Lock()
|
|
||||||
s.sessions[sid] = session
|
|
||||||
s.Unlock()
|
|
||||||
|
|
||||||
// Do the session's work.
|
// Do the session's work.
|
||||||
session.work()
|
session.work()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user