Merge branch 'main' of https://github.com/Malckyor/Erupe into pr/81

This commit is contained in:
Matthew
2023-11-19 14:35:25 -05:00
120 changed files with 2321 additions and 2663 deletions

View File

@@ -1,6 +1,15 @@
name: Build name: Build
on: [push] on:
push:
paths:
- 'common/**'
- 'config/**'
- 'network/**'
- 'server/**'
- 'go.mod'
- 'go.sum'
- 'main.go'
jobs: jobs:
build: build:

125
README.md
View File

@@ -6,10 +6,13 @@
- PlayStation 3 - PlayStation 3
- PlayStation Vita - PlayStation Vita
- Wii U (Up to Z2) - Wii U (Up to Z2)
### Versions ### Versions (ClientMode)
- ZZ - All versions after HR compression (G10-ZZ) have been tested extensively and have great functionality.
- Z2 - All versions available on Wii U (G3-Z2) have been tested and should have good functionality.
- Z1 - The second oldest found version is Forward.4 (FW.4), this version has basic functionality.
- The oldest found version is Season 6.0 (S6.0), however functionality is very limited.
If you have an **installed** copy of Monster Hunter Frontier on an old hard drive, **please** get in contact so we can archive it!
## Setup ## Setup
@@ -32,116 +35,4 @@ If you want to modify or compile Erupe yourself, please read on.
## Resources ## Resources
- [Quest and Scenario Binary Files](https://files.catbox.moe/xf0l7w.7z) - [Quest and Scenario Binary Files](https://files.catbox.moe/xf0l7w.7z)
- [PewPewDojo Discord](https://discord.gg/CFnzbhQ) - [Mezeporta Square Discord](https://discord.gg/DnwcpXM488)
## Configuration
This portion of the documentation goes over the `config.json` file.
### General Configuration
| Variable | Description | Default | Options |
|------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|---------------------------------|
| Host | The IP or host address the server is running from | 127.0.0.1 | |
| BinPath | The bin path folder is where you place files needed for various parts of the game such as scenario and quest files | bin | |
| Language | This is the language the server will run in. Only English `en` and Japanese `ja` are available, if you wish to contribute to tranlation, get in touch | en | en/jp |
| DisableSoftCrash | | false | |
| HideLoginNotice | This hides the notices that appear on login from `LoginNotices` | true | |
| LoginNotices | This is where you place notices for users, you can have multiple notices | | |
| PatchServerManifest | | | |
| PatchServerFile | | | |
| ScreenshotAPIURL | This is the URL you want user sreenshots to go to | | |
| DeleteOnSaveCorruption | This option deletes a users save from the database if they corrupt it, can be used as punishment for cheaters | false | |
| ClientMode | This tells the server what client version it should target | ZZ | Check compatible versions above |
| DevMode | This enables DevModeOptions to be configured | true | |
### `DevModeOptions` Configuraiton
| Variable | Description | Default | Options |
|----------------------|---------------------------------------------------------------------------------------------|----------|----------------------------------|
| AutoCreateAccount | This allows users that don't exist to auto create there account from initial login | true | |
| CleanDB | This cleans the database down | false | |
| MaxLauncherHR | This sets the launcher value to HR7 to allow you to break World HR requirements | false | |
| LogInboundMessages | This will allow inbound messages to be logged to stdout | false | |
| LogOutboundMessages | This will allow outbound messages to be logged to stdout | false | |
| MaxHexdumpLength | This is the maximum amount of hex bytes that will be dumped to stdout | 0 | |
| DivaEvent | This overrides the Diva event stage in game | 2 | 0/1/2/3/-1 |
| FestaEvent | This overrides the Hunter Festival event stage in game | 2 | 0/1/2/3/-1 |
| TournamentEvent | This overrides the Hunter Tournament event stage in game | 2 | 0/1/2/3/-1 |
| MezFesEvent | Enables whether the MezFes event & World are active | true | |
| MezFesAlt | Switches the multiplayer MezFes event | false | |
| DisableTokenCheck | This disables the random token that is generated at login from being checked, very insecure | false | |
| QuestDebugTools | Enable various quest debug logs | false | |
| EarthStatusOverride | Enables Pallone Fest, Tower and Conquest War events | 0 | 2=Conquest, 11=Pallone, 21=Tower |
| EarthIDOverride | A random event ID | 0 | |
| EarthMonsterOverride | Sets the ID of the monster targeted in the Conquest War | 0 | |
| SaveDumps.Enables | Enables save dumps to a folder that is set at `SaveDumps.OutputDir` | true | |
| SaveDumps.OutputDir | The folder that save dumps are saved to | savedata | |
### `GameplayOptions` Configuraiton
| Variable | Description | Default | Options |
|----------------------|-----------------------------------------------------------------------------|---------|---------|
| FeaturedWeapons | Number of Active Feature weapons to generate daily | 0 | |
| MaximumNP | Maximum number of NP held by a player | 100000 | |
| MaximumRP | Maximum number of RP held by a player | 100000 | |
| DisableLoginBoost | Disables the Login Boost system | false | |
| DisableBoostTime | Disables the daily NetCafe Boost Time | false | |
| BoostTimeDuration | The number of minutes NetCafe Boost Time lasts for | 120 | |
| GuildMealDuration | The number of minutes a Guild Meal can be activated for after cooking | 60 | |
| BonusQuestAllowance | Number of Bonus Point Quests to allow daily | 3 | |
| DailyQuestAllowance | Number of Daily Quests to allow daily | 1 | |
| MezfesSoloTickets | Number of solo tickets given weekly | 10 | |
| MezfesGroupTickets | Number of group tickets given weekly | 4 | |
| GUrgentRate | Adjusts the rate of G Urgent quests spawning | 10 | |
| GCPMultiplier | Adjusts the multiplier of GCP rewarded for quest completion | 1.00 | |
| GRPMultiplier | Adjusts the multiplier of G Rank Points rewarded for quest completion | 1.00 | |
| GSRPMultiplier | Adjusts the multiplier of G Skill Rank Points rewarded for quest completion | 1.00 | |
| GZennyMultiplier | Adjusts the multiplier of G Zenny rewarded for quest completion | 1.00 | |
| MaterialMultiplier | Adjusts the multiplier of Monster Materials rewarded for quest completion | 1.00 | |
| ExtraCarves | Grant n extra chances to carve ALL carcasses | 0 | |
| DisableHunterNavi | Disables the Hunter Navi | false | |
| EnableHiganjimaEvent | Enables the Higanjima event in the Rasta Bar | false | |
| EnableNierEvent | Enables the Nier event in the Rasta Bar | false | |
| DisableRoad | Disables the Hunting Road | false | |
### Discord
There is limited Discord capability in Erupe. The feature allows you to replay messages from your server into a channel.
This may be either be removed or revamped in a future version.
### Commands
There are several chat commands that can be turned on and off. Most of them are really for admins or debugging purposes.
| Name | command | Description | Options |
|----------|----------------|--------------------------------------------|---------------------|
| Rights | !rights VALUE | Sets the rights integer for your account | |
| Teleport | !tele X,Y | Teleports user to specific x,y coordinate | |
| Reload | !reload | Reloads all users and character objects | |
| KeyQuest | !kqf FLAGS | Sets the Key Quest Flag for your character | |
| Course | !course OPTION | Enables/Disables a course for your account | HL,EX,Premium,Boost |
| PSN | !psn USERNAME | Links the specified PSN to your account | |
### Ravi Sub Commands
| Name | command | Description |
|----------|----------------------------------|-------------------------------|
| Raviente | !ravi start | Starts Ravi Event |
| Raviente | !ravi cm / !ravi checkmultiplier | Checks Ravi Damage Multiplier |
| Raviente | !ravi ss | Send Sedation Support |
| Raviente | !ravi sr | Send Resurrection Support |
| Raviente | !ravi rs | Request Sedation Support |
## World `Entries` config
| Config Item | Description | Options |
|-------------|------------------|------------------------------------------------------------|
| Type | Server type. | 1=Normal, 2=Cities, 3=Newbie, 4=Tavern, 5=Return, 6=MezFes |
| Season | Server activity. | 0=Green/Breeding, 1=Orange/Warm, 2=Blue/Cold |
### `Recommend`
This sets the types of quest that can be ordered from a world.
* 0 = All quests
* 1 = Up to 2 star quests
* 2 = Up to 4 star quests
* 4 = All Quests in HR (Enables G Experience Tab)
* 5 = Only G rank quests
* 6 = Mini games world there is no place to order quests

View File

@@ -0,0 +1,11 @@
BEGIN;
-- Adds a Distribution that can be accepted up to 20 times that gives one of Item Type 30 (Item Box extra page)
INSERT INTO distribution (type, event_name, description, times_acceptable) VALUES (1, 'Extra Item Storage', '~C05Adds one new page to your Item Box.', 20);
INSERT INTO distribution_items (distribution_id, item_type, quantity) VALUES ((SELECT id FROM distribution ORDER BY id DESC LIMIT 1), 30, 1);
-- Adds a Distribution that can be accepted up to 20 times that gives one of Item Type 31 (Equipment Box extra page)
INSERT INTO distribution (type, event_name, description, times_acceptable) VALUES (1, 'Extra Equipment Storage', '~C05Adds one new page to your Equipment Box.', 20);
INSERT INTO distribution_items (distribution_id, item_type, quantity) VALUES ((SELECT id FROM distribution ORDER BY id DESC LIMIT 1), 31, 1);
END;

View File

@@ -0,0 +1,178 @@
BEGIN;
INSERT INTO public.scenario_counter
(scenario_id, category_id)
VALUES
(17,0),
(93,1),
(92,1),
(81,1),
(91,1),
(90,1),
(89,1),
(88,1),
(87,1),
(86,1),
(85,1),
(84,1),
(83,1),
(82,1),
(87,3),
(88,3),
(89,3),
(90,3),
(91,3),
(92,3),
(83,3),
(86,3),
(60,3),
(58,3),
(59,3),
(27,3),
(25,3),
(26,3),
(23,3),
(2,3),
(3,3),
(4,3),
(31,3),
(32,3),
(33,3),
(34,3),
(35,3),
(36,3),
(37,3),
(40,3),
(38,3),
(39,3),
(48,3),
(12,3),
(13,3),
(30,3),
(29,3),
(46,3),
(0,4),
(1,4),
(2,4),
(3,4),
(4,4),
(5,4),
(6,4),
(7,4),
(8,4),
(9,4),
(10,4),
(11,4),
(12,4),
(13,4),
(14,4),
(50,5),
(51,5),
(52,5),
(53,5),
(54,5),
(55,5),
(56,5),
(58,5),
(63,5),
(64,5),
(65,5),
(67,5),
(71,5),
(75,5),
(61,5),
(68,5),
(66,5),
(76,5),
(70,5),
(77,5),
(72,5),
(74,5),
(73,5),
(78,5),
(69,5),
(62,5),
(79,5),
(0,6),
(1,6),
(2,6),
(3,6),
(4,6),
(5,6),
(6,6),
(7,6),
(8,6),
(9,6),
(17,6),
(10,6),
(11,6),
(12,6),
(13,6),
(14,6),
(15,6),
(16,6),
(50,7),
(53,7),
(62,7),
(52,7),
(56,7),
(51,7),
(49,7),
(54,7),
(57,7),
(55,7),
(61,7),
(58,7),
(60,7),
(59,7),
(42,7),
(48,7),
(40,7),
(39,7),
(43,7),
(46,7),
(41,7),
(44,7),
(45,7),
(47,7),
(37,7),
(34,7),
(33,7),
(32,7),
(28,7),
(26,7),
(36,7),
(38,7),
(35,7),
(27,7),
(30,7),
(31,7),
(29,7),
(24,7),
(23,7),
(22,7),
(21,7),
(25,7),
(20,7),
(7,7),
(9,7),
(13,7),
(16,7),
(12,7),
(14,7),
(15,7),
(19,7),
(10,7),
(8,7),
(11,7),
(18,7),
(17,7),
(6,7),
(5,7),
(4,7),
(3,7),
(2,7),
(1,7),
(0,7);
END;

366
common/mhfmon/mhfmon.go Normal file
View File

@@ -0,0 +1,366 @@
package mhfmon
const (
Mon0 = iota
Rathian
Fatalis
Kelbi
Mosswine
Bullfango
YianKutKu
LaoShanLung
Cephadrome
Felyne
VeggieElder
Rathalos
Aptonoth
Genprey
Diablos
Khezu
Velociprey
Gravios
Mon18
Vespoid
Gypceros
Plesioth
Basarios
Melynx
Hornetaur
Apceros
Monoblos
Velocidrome
Gendrome
Mon29
Ioprey
Iodrome
Mon32
Kirin
Cephalos
Giaprey
CrimsonFatalis
PinkRathian
BlueYianKutKu
PurpleGypceros
YianGaruga
SilverRathalos
GoldRathian
BlackDiablos
WhiteMonoblos
RedKhezu
GreenPlesioth
BlackGravios
DaimyoHermitaur
AzureRathalos
AshenLaoShanLung
Blangonga
Congalala
Rajang
KushalaDaora
ShenGaoren
GreatThunderbug
Shakalaka
YamaTsukami
Chameleos
RustedKushalaDaora
Blango
Conga
Remobra
Lunastra
Teostra
Hermitaur
ShogunCeanataur
Bulldrome
Anteka
Popo
WhiteFatalis
Mon72
Ceanataur
Hypnocatrice
Lavasioth
Tigrex
Akantor
BrightHypnoc
RedLavasioth
Espinas
OrangeEspinas
WhiteHypnoc
AqraVashimu
AqraJebia
Berukyurosu
Mon86
Mon87
Mon88
Pariapuria
WhiteEspinas
KamuOrugaron
NonoOrugaron
Raviente
Dyuragaua
Doragyurosu
Gurenzeburu
Burukku
Erupe
Rukodiora
Unknown
Gogomoa
Kokomoa
TaikunZamuza
Abiorugu
Kuarusepusu
Odibatorasu
Disufiroa
Rebidiora
Anorupatisu
Hyujikiki
Midogaron
Giaorugu
MiRu
Farunokku
Pokaradon
Shantien
Pokara
Mon118
Goruganosu
Aruganosu
Baruragaru
Zerureusu
Gougarf
Uruki
Forokururu
Meraginasu
Diorex
GarubaDaora
Inagami
Varusaburosu
Poborubarumu
Block1Duremudira
Mon133
Mon134
Mon135
Mon136
Mon137
Mon138
Gureadomosu
Harudomerugu
Toridcless
Gasurabazura
Kusubami
YamaKurai
Block2Duremudira
Zinogre
Deviljho
Brachydios
BerserkRaviente
ToaTesukatora
Barioth
Uragaan
StygianZinogre
Guanzorumu
SavageDeviljho
Mon156
Egyurasu
Voljang
Nargacuga
Keoaruboru
Zenaserisu
GoreMagala
BlinkingNargacuga
ShagaruMagala
Amatsu
Eruzerion
MusouDuremudira
Mon168
Seregios
Bogabadorumu
Mon171
MusouBogabadorumu
CostumedUruki
MusouZerureusu
Rappy
KingShakalaka
)
type Monster struct {
Name string
Large bool
}
var Monsters = []Monster{
{"Mon0", false},
{"Rathian", true},
{"Fatalis", true},
{"Kelbi", false},
{"Mosswine", false},
{"Bullfango", false},
{"Yian Kut-Ku", true},
{"Lao-Shan Lung", true},
{"Cephadrome", true},
{"Felyne", false},
{"Veggie Elder", false},
{"Rathalos", true},
{"Aptonoth", false},
{"Genprey", false},
{"Diablos", true},
{"Khezu", true},
{"Velociprey", false},
{"Gravios", true},
{"Mon18", false},
{"Vespoid", false},
{"Gypceros", true},
{"Plesioth", true},
{"Basarios", true},
{"Melynx", false},
{"Hornetaur", false},
{"Apceros", false},
{"Monoblos", true},
{"Velocidrome", true},
{"Gendrome", true},
{"Mon29", false},
{"Ioprey", false},
{"Iodrome", true},
{"Mon32", false},
{"Kirin", true},
{"Cephalos", false},
{"Giaprey", false},
{"Crimson Fatalis", true},
{"Pink Rathian", true},
{"Blue Yian Kut-Ku", true},
{"Purple Gypceros", true},
{"Yian Garuga", true},
{"Silver Rathalos", true},
{"Gold Rathian", true},
{"Black Diablos", true},
{"White Monoblos", true},
{"Red Khezu", true},
{"Green Plesioth", true},
{"Black Gravios", true},
{"Daimyo Hermitaur", true},
{"Azure Rathalos", true},
{"Ashen Lao-Shan Lung", true},
{"Blangonga", true},
{"Congalala", true},
{"Rajang", true},
{"Kushala Daora", true},
{"Shen Gaoren", true},
{"Great Thunderbug", false},
{"Shakalaka", false},
{"Yama Tsukami", true},
{"Chameleos", true},
{"Rusted Kushala Daora", true},
{"Blango", false},
{"Conga", false},
{"Remobra", false},
{"Lunastra", true},
{"Teostra", true},
{"Hermitaur", false},
{"Shogun Ceanataur", true},
{"Bulldrome", true},
{"Anteka", false},
{"Popo", false},
{"White Fatalis", true},
{"Mon72", false},
{"Ceanataur", false},
{"Hypnocatrice", true},
{"Lavasioth", true},
{"Tigrex", true},
{"Akantor", true},
{"Bright Hypnocatrice", true},
{"Red Lavasioth", true},
{"Espinas", true},
{"Orange Espinas", true},
{"White Hypnocatrice", true},
{"Aqra Vashimu", true},
{"Aqra Jebia", true},
{"Berukyurosu", true},
{"Mon86", false},
{"Mon87", false},
{"Mon88", false},
{"Pariapuria", true},
{"White Espinas", true},
{"Kamu Orugaron", true},
{"Nono Orugaron", true},
{"Raviente", true}, // + Violent
{"Dyuragaua", true},
{"Doragyurosu", true},
{"Gurenzeburu", true},
{"Burukku", false},
{"Erupe", false},
{"Rukodiora", true},
{"Unknown", true},
{"Gogomoa", true},
{"Kokomoa", false},
{"Taikun Zamuza", true},
{"Abiorugu", true},
{"Kuarusepusu", true},
{"Odibatorasu", true},
{"Disufiroa", true},
{"Rebidiora", true},
{"Anorupatisu", true},
{"Hyujikiki", true},
{"Midogaron", true},
{"Giaorugu", true},
{"Mi-Ru", true}, // + Musou
{"Farunokku", true},
{"Pokaradon", true},
{"Shantien", true},
{"Pokara", false},
{"Mon118", false},
{"Goruganosu", true},
{"Aruganosu", true},
{"Baruragaru", true},
{"Zerureusu", true},
{"Gougarf", true}, // Both
{"Uruki", false},
{"Forokururu", true},
{"Meraginasu", true},
{"Diorex", true},
{"Garuba Daora", true},
{"Inagami", true},
{"Varusablos", true},
{"Poborubarumu", true},
{"1st Block Duremudira", true},
{"Mon133", false},
{"Mon134", false},
{"Mon135", false},
{"Mon136", false},
{"Mon137", false},
{"Mon138", false},
{"Gureadomosu", true},
{"Harudomerugu", true},
{"Toridcless", true},
{"Gasurabazura", true},
{"Kusubami", false},
{"Yama Kurai", true},
{"2nd Block Duremudira", true},
{"Zinogre", true},
{"Deviljho", true},
{"Brachydios", true},
{"Berserk Raviente", true},
{"Toa Tesukatora", true},
{"Barioth", true},
{"Uragaan", true},
{"Stygian Zinogre", true},
{"Guanzorumu", true},
{"Savage Deviljho", true}, // + Starving/Heavenly
{"Mon156", false},
{"Egyurasu", false},
{"Voljang", true},
{"Nargacuga", true},
{"Keoaruboru", true},
{"Zenaserisu", true},
{"Gore Magala", true},
{"Blinking Nargacuga", true},
{"Shagaru Magala", true},
{"Amatsu", true},
{"Eruzerion", true}, // + Musou
{"Musou Duremudira", true},
{"Mon168", false},
{"Seregios", true},
{"Bogabadorumu", true},
{"Mon171", false},
{"Musou Bogabadorumu", true},
{"Costumed Uruki", false},
{"Musou Zerureusu", true},
{"Rappy", false},
{"King Shakalaka", false},
}

View File

@@ -69,7 +69,7 @@ func CSVRemove(csv string, v int) string {
func CSVContains(csv string, v int) bool { func CSVContains(csv string, v int) bool {
s := strings.Split(csv, ",") s := strings.Split(csv, ",")
for i := 0; i < len(s); i++ { for i := 0; i < len(s); i++ {
j, _ := strconv.ParseInt(s[i], 10, 64) j, _ := strconv.ParseInt(s[i], 10, 32)
if int(j) == v { if int(j) == v {
return true return true
} }
@@ -92,7 +92,7 @@ func CSVElems(csv string) []int {
} }
s := strings.Split(csv, ",") s := strings.Split(csv, ",")
for i := 0; i < len(s); i++ { for i := 0; i < len(s); i++ {
j, _ := strconv.ParseInt(s[i], 10, 64) j, _ := strconv.ParseInt(s[i], 10, 32)
r = append(r, int(j)) r = append(r, int(j))
} }
return r return r

View File

@@ -12,13 +12,15 @@
"ScreenshotAPIURL": "", "ScreenshotAPIURL": "",
"DeleteOnSaveCorruption": false, "DeleteOnSaveCorruption": false,
"ClientMode": "ZZ", "ClientMode": "ZZ",
"QuestCacheExpiry": 300,
"DevMode": true, "DevMode": true,
"DevModeOptions": { "DevModeOptions": {
"AutoCreateAccount": true, "AutoCreateAccount": true,
"CleanDB": false, "CleanDB": false,
"MaxLauncherHR": false, "MaxLauncherHR": false,
"LogInboundMessages": true, "LogInboundMessages": false,
"LogOutboundMessages": true, "LogOutboundMessages": false,
"LogMessageData": false,
"MaxHexdumpLength": 256, "MaxHexdumpLength": 256,
"DivaEvent": 0, "DivaEvent": 0,
"FestaEvent": -1, "FestaEvent": -1,
@@ -40,6 +42,7 @@
"MaximumNP": 100000, "MaximumNP": 100000,
"MaximumRP": 50000, "MaximumRP": 50000,
"MaximumFP": 120000, "MaximumFP": 120000,
"TreasureHuntExpiry": 604800,
"DisableLoginBoost": false, "DisableLoginBoost": false,
"DisableBoostTime": false, "DisableBoostTime": false,
"BoostTimeDuration": 120, "BoostTimeDuration": 120,
@@ -54,7 +57,7 @@
"BerserkRavienteMaxPlayers": 32, "BerserkRavienteMaxPlayers": 32,
"ExtremeRavienteMaxPlayers": 32, "ExtremeRavienteMaxPlayers": 32,
"SmallBerserkRavienteMaxPlayers": 8, "SmallBerserkRavienteMaxPlayers": 8,
"GUrgentRate": 10, "GUrgentRate": 0.10,
"GCPMultiplier": 1.00, "GCPMultiplier": 1.00,
"GRPMultiplier": 1.00, "GRPMultiplier": 1.00,
"GSRPMultiplier": 1.00, "GSRPMultiplier": 1.00,
@@ -77,31 +80,31 @@
{ {
"Name": "Rights", "Name": "Rights",
"Enabled": false, "Enabled": false,
"Prefix": "!rights" "Prefix": "rights"
}, { }, {
"Name": "Raviente", "Name": "Raviente",
"Enabled": true, "Enabled": true,
"Prefix": "!ravi" "Prefix": "ravi"
}, { }, {
"Name": "Teleport", "Name": "Teleport",
"Enabled": false, "Enabled": false,
"Prefix": "!tele" "Prefix": "tele"
}, { }, {
"Name": "Reload", "Name": "Reload",
"Enabled": true, "Enabled": true,
"Prefix": "!reload" "Prefix": "reload"
}, { }, {
"Name": "KeyQuest", "Name": "KeyQuest",
"Enabled": false, "Enabled": false,
"Prefix": "!kqf" "Prefix": "kqf"
}, { }, {
"Name": "Course", "Name": "Course",
"Enabled": true, "Enabled": true,
"Prefix": "!course" "Prefix": "course"
}, { }, {
"Name": "PSN", "Name": "PSN",
"Enabled": true, "Enabled": true,
"Prefix": "!psn" "Prefix": "psn"
} }
], ],
"Courses": [ "Courses": [

View File

@@ -58,7 +58,7 @@ const (
) )
var versionStrings = []string{"S1.0", "S1.5", "S2.0", "S2.5", "S3.0", "S3.5", "S4.0", "S5.0", "S5.5", "S6.0", "S7.0", var versionStrings = []string{"S1.0", "S1.5", "S2.0", "S2.5", "S3.0", "S3.5", "S4.0", "S5.0", "S5.5", "S6.0", "S7.0",
"S8.0", "S8.5", "S9", "S10", "FW.1", "FW.2", "FW.3", "FW.4", "FW.5", "G1", "G2", "G3", "G3.1", "G3.2", "GG", "G5", "S8.0", "S8.5", "S9.0", "S10", "FW.1", "FW.2", "FW.3", "FW.4", "FW.5", "G1", "G2", "G3", "G3.1", "G3.2", "GG", "G5",
"G5.1", "G5.2", "G6", "G6.1", "G7", "G8", "G8.1", "G9", "G9.1", "G10", "G10.1", "Z1", "Z2", "ZZ"} "G5.1", "G5.2", "G6", "G6.1", "G7", "G8", "G8.1", "G9", "G9.1", "G10", "G10.1", "Z1", "Z2", "ZZ"}
func (m Mode) String() string { func (m Mode) String() string {
@@ -79,6 +79,7 @@ type Config struct {
DeleteOnSaveCorruption bool // Attempts to save corrupted data will flag the save for deletion DeleteOnSaveCorruption bool // Attempts to save corrupted data will flag the save for deletion
ClientMode string ClientMode string
RealClientMode Mode RealClientMode Mode
QuestCacheExpiry int // Number of seconds to keep quest data cached
DevMode bool DevMode bool
DevModeOptions DevModeOptions DevModeOptions DevModeOptions
@@ -100,6 +101,7 @@ type DevModeOptions struct {
MaxLauncherHR bool // Sets the HR returned in the launcher to HR7 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.
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
LogMessageData bool // Log all bytes transferred as a hexdump
MaxHexdumpLength int // Maximum number of bytes printed when logs are enabled MaxHexdumpLength int // Maximum number of bytes printed when logs are enabled
DivaEvent int // Diva Defense event status DivaEvent int // Diva Defense event status
FestaEvent int // Hunter's Festa event status FestaEvent int // Hunter's Festa event status
@@ -125,6 +127,8 @@ type GameplayOptions struct {
MaximumNP int // Maximum number of NP held by a player MaximumNP int // Maximum number of NP held by a player
MaximumRP uint16 // Maximum number of RP held by a player MaximumRP uint16 // Maximum number of RP held by a player
MaximumFP uint32 // Maximum number of FP held by a player MaximumFP uint32 // Maximum number of FP held by a player
TreasureHuntExpiry uint32 // Seconds until a Clan Treasure Hunt will expire
TreasureHuntPartnyaCooldown uint32 // Seconds until a Partnya can be assigned to another Clan Treasure Hunt
DisableLoginBoost bool // Disables the Login Boost system DisableLoginBoost bool // Disables the Login Boost system
DisableBoostTime bool // Disables the daily NetCafe Boost Time DisableBoostTime bool // Disables the daily NetCafe Boost Time
BoostTimeDuration int // The number of minutes NetCafe Boost Time lasts for BoostTimeDuration int // The number of minutes NetCafe Boost Time lasts for
@@ -139,7 +143,7 @@ type GameplayOptions struct {
BerserkRavienteMaxPlayers uint8 BerserkRavienteMaxPlayers uint8
ExtremeRavienteMaxPlayers uint8 ExtremeRavienteMaxPlayers uint8
SmallBerserkRavienteMaxPlayers uint8 SmallBerserkRavienteMaxPlayers uint8
GUrgentRate uint16 // Adjusts the rate of G Urgent quests spawning GUrgentRate float32 // Adjusts the rate of G Urgent quests spawning
GCPMultiplier float32 // Adjusts the multiplier of GCP rewarded for quest completion GCPMultiplier float32 // Adjusts the multiplier of GCP rewarded for quest completion
GRPMultiplier float32 // Adjusts the multiplier of G Rank Points rewarded for quest completion GRPMultiplier float32 // Adjusts the multiplier of G Rank Points rewarded for quest completion
GSRPMultiplier float32 // Adjusts the multiplier of G Skill Rank Points rewarded for quest completion GSRPMultiplier float32 // Adjusts the multiplier of G Skill Rank Points rewarded for quest completion

View File

@@ -126,6 +126,7 @@ 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(`UPDATE guild_characters SET treasure_hunt=NULL`)
// Clean the DB if the option is on. // Clean the DB if the option is on.
if config.DevMode && config.DevModeOptions.CleanDB { if config.DevMode && config.DevModeOptions.CleanDB {

View File

@@ -1,19 +1,19 @@
package mhfpacket 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"
) )
// MsgMhfAcquireFesta represents the MSG_MHF_ACQUIRE_FESTA // MsgMhfAcquireFesta represents the MSG_MHF_ACQUIRE_FESTA
type MsgMhfAcquireFesta struct { type MsgMhfAcquireFesta struct {
AckHandle uint32 AckHandle uint32
FestaID uint32 FestaID uint32
GuildID uint32 GuildID uint32
Unk uint16 Unk uint8
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -23,11 +23,12 @@ func (m *MsgMhfAcquireFesta) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfAcquireFesta) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfAcquireFesta) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.FestaID = bf.ReadUint32() m.FestaID = bf.ReadUint32()
m.GuildID = bf.ReadUint32() m.GuildID = bf.ReadUint32()
m.Unk = bf.ReadUint16() m.Unk = bf.ReadUint8()
return nil bf.ReadUint8() // Zeroed
return nil
} }
// Build builds a binary packet from the current data. // Build builds a binary packet from the current data.

View File

@@ -12,7 +12,7 @@ import (
type MsgMhfAcquireGuildTresure struct { type MsgMhfAcquireGuildTresure struct {
AckHandle uint32 AckHandle uint32
HuntID uint32 HuntID uint32
Unk uint8 Unk bool
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -24,7 +24,7 @@ func (m *MsgMhfAcquireGuildTresure) Opcode() network.PacketID {
func (m *MsgMhfAcquireGuildTresure) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfAcquireGuildTresure) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.HuntID = bf.ReadUint32() m.HuntID = bf.ReadUint32()
m.Unk = bf.ReadUint8() m.Unk = bf.ReadBool()
return nil return nil
} }

View File

@@ -11,9 +11,9 @@ import (
// MsgMhfAcquireMonthlyItem represents the MSG_MHF_ACQUIRE_MONTHLY_ITEM // MsgMhfAcquireMonthlyItem represents the MSG_MHF_ACQUIRE_MONTHLY_ITEM
type MsgMhfAcquireMonthlyItem struct { type MsgMhfAcquireMonthlyItem struct {
AckHandle uint32 AckHandle uint32
Unk0 uint16 Unk0 uint8
Unk1 uint16 Unk1 uint8
Unk2 uint32 Unk2 uint16
Unk3 uint32 Unk3 uint32
} }
@@ -25,10 +25,11 @@ func (m *MsgMhfAcquireMonthlyItem) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfAcquireMonthlyItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfAcquireMonthlyItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint16() m.Unk0 = bf.ReadUint8()
m.Unk1 = bf.ReadUint16() m.Unk1 = bf.ReadUint8()
m.Unk2 = bf.ReadUint32() m.Unk2 = bf.ReadUint16()
m.Unk3 = bf.ReadUint32() m.Unk3 = bf.ReadUint32()
bf.ReadUint32() // Zeroed
return nil return nil
} }

View File

@@ -11,9 +11,7 @@ import (
// MsgMhfAcquireTitle represents the MSG_MHF_ACQUIRE_TITLE // MsgMhfAcquireTitle represents the MSG_MHF_ACQUIRE_TITLE
type MsgMhfAcquireTitle struct { type MsgMhfAcquireTitle struct {
AckHandle uint32 AckHandle uint32
Unk0 uint16 TitleIDs []uint16
Unk1 uint16
TitleID uint16
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -24,9 +22,11 @@ func (m *MsgMhfAcquireTitle) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfAcquireTitle) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfAcquireTitle) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint16() titles := int(bf.ReadUint16())
m.Unk1 = bf.ReadUint16() bf.ReadUint16() // Zeroed
m.TitleID = bf.ReadUint16() for i := 0; i < titles; i++ {
m.TitleIDs = append(m.TitleIDs, bf.ReadUint16())
}
return nil return nil
} }

View File

@@ -14,7 +14,7 @@ type MsgMhfAnnounce struct {
IPAddress uint32 IPAddress uint32
Port uint16 Port uint16
StageID []byte StageID []byte
Type uint8 Data *byteframe.ByteFrame
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -31,8 +31,7 @@ func (m *MsgMhfAnnounce) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientCon
_ = bf.ReadUint8() _ = bf.ReadUint8()
_ = bf.ReadUint8() _ = bf.ReadUint8()
m.StageID = bf.ReadBytes(32) m.StageID = bf.ReadBytes(32)
_ = bf.ReadUint32() m.Data = byteframe.NewByteFrameFromBytes(bf.ReadBytes(uint(bf.ReadUint32())))
m.Type = bf.ReadUint8()
return nil return nil
} }

View File

@@ -1,18 +1,19 @@
package mhfpacket package mhfpacket
import ( import (
"errors"
"erupe-ce/common/byteframe"
"erupe-ce/network" "erupe-ce/network"
"erupe-ce/network/clientctx" "erupe-ce/network/clientctx"
"erupe-ce/common/byteframe"
) )
// MsgMhfApplyDistItem represents the MSG_MHF_APPLY_DIST_ITEM // MsgMhfApplyDistItem represents the MSG_MHF_APPLY_DIST_ITEM
type MsgMhfApplyDistItem struct { type MsgMhfApplyDistItem struct {
AckHandle uint32 AckHandle uint32
DistributionType uint8 DistributionType uint8
DistributionID uint32 DistributionID uint32
Unk2 uint32 Unk2 uint32
Unk3 uint32 Unk3 uint32
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -32,10 +33,5 @@ func (m *MsgMhfApplyDistItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Clie
// Build builds a binary packet from the current data. // Build builds a binary packet from the current data.
func (m *MsgMhfApplyDistItem) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfApplyDistItem) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
bf.WriteUint32(m.AckHandle) return errors.New("NOT IMPLEMENTED")
bf.WriteUint8(m.DistributionType) }
bf.WriteUint32(m.DistributionID)
bf.WriteUint32(m.Unk2)
bf.WriteUint32(m.Unk3)
return nil
}

View File

@@ -1,9 +1,10 @@
package mhfpacket package mhfpacket
import ( import (
"errors"
"erupe-ce/common/byteframe"
"erupe-ce/network" "erupe-ce/network"
"erupe-ce/network/clientctx" "erupe-ce/network/clientctx"
"erupe-ce/common/byteframe"
) )
// MsgMhfArrangeGuildMember represents the MSG_MHF_ARRANGE_GUILD_MEMBER // MsgMhfArrangeGuildMember represents the MSG_MHF_ARRANGE_GUILD_MEMBER
@@ -22,11 +23,11 @@ func (m *MsgMhfArrangeGuildMember) Opcode() network.PacketID {
func (m *MsgMhfArrangeGuildMember) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfArrangeGuildMember) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.GuildID = bf.ReadUint32() m.GuildID = bf.ReadUint32()
charCount := bf.ReadUint16() bf.ReadUint8() // Zeroed
charCount := int(bf.ReadUint8())
m.CharIDs = make([]uint32, charCount) m.CharIDs = make([]uint32, charCount)
for i := uint16(0); i < charCount; i++ { for i := 0; i < charCount; i++ {
m.CharIDs[i] = bf.ReadUint32() m.CharIDs[i] = bf.ReadUint32()
} }
@@ -35,13 +36,5 @@ func (m *MsgMhfArrangeGuildMember) Parse(bf *byteframe.ByteFrame, ctx *clientctx
// Build builds a binary packet from the current data. // Build builds a binary packet from the current data.
func (m *MsgMhfArrangeGuildMember) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfArrangeGuildMember) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
bf.WriteUint32(m.AckHandle) return errors.New("NOT IMPLEMENTED")
bf.WriteUint32(m.GuildID)
bf.WriteUint16(uint16(len(m.CharIDs)))
for _, charID := range m.CharIDs {
bf.WriteUint32(charID)
}
return nil
} }

View File

@@ -1,9 +1,10 @@
package mhfpacket package mhfpacket
import ( import (
"errors"
"erupe-ce/common/byteframe"
"erupe-ce/network" "erupe-ce/network"
"erupe-ce/network/clientctx" "erupe-ce/network/clientctx"
"erupe-ce/common/byteframe"
) )
// MsgMhfCheckDailyCafepoint represents the MSG_MHF_CHECK_DAILY_CAFEPOINT // MsgMhfCheckDailyCafepoint represents the MSG_MHF_CHECK_DAILY_CAFEPOINT
@@ -25,7 +26,5 @@ func (m *MsgMhfCheckDailyCafepoint) Parse(bf *byteframe.ByteFrame, ctx *clientct
} }
func (m *MsgMhfCheckDailyCafepoint) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfCheckDailyCafepoint) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
bf.WriteUint32(m.AckHandle) return errors.New("NOT IMPLEMENTED")
bf.WriteUint32(m.Unk)
return nil
} }

View File

@@ -12,7 +12,6 @@ import (
type MsgMhfCheckMonthlyItem struct { type MsgMhfCheckMonthlyItem struct {
AckHandle uint32 AckHandle uint32
Type uint8 Type uint8
Unk []byte
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -24,7 +23,9 @@ func (m *MsgMhfCheckMonthlyItem) Opcode() network.PacketID {
func (m *MsgMhfCheckMonthlyItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfCheckMonthlyItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Type = bf.ReadUint8() m.Type = bf.ReadUint8()
m.Unk = bf.ReadBytes(3) bf.ReadUint8() // Zeroed
bf.ReadUint8() // Zeroed
bf.ReadUint8() // Zeroed
return nil return nil
} }

View File

@@ -12,7 +12,6 @@ type MsgMhfCheckWeeklyStamp struct {
AckHandle uint32 AckHandle uint32
StampType string StampType string
Unk1 bool Unk1 bool
Unk2 uint16 // Hardcoded 0 in the binary
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -31,7 +30,7 @@ func (m *MsgMhfCheckWeeklyStamp) Parse(bf *byteframe.ByteFrame, ctx *clientctx.C
m.StampType = "ex" m.StampType = "ex"
} }
m.Unk1 = bf.ReadBool() m.Unk1 = bf.ReadBool()
m.Unk2 = bf.ReadUint16() bf.ReadUint16() // Zeroed
return nil return nil
} }

View File

@@ -12,8 +12,6 @@ import (
// MsgMhfCreateGuild represents the MSG_MHF_CREATE_GUILD // MsgMhfCreateGuild represents the MSG_MHF_CREATE_GUILD
type MsgMhfCreateGuild struct { type MsgMhfCreateGuild struct {
AckHandle uint32 AckHandle uint32
Unk0 uint8
Unk1 uint8
Name string Name string
} }
@@ -25,9 +23,8 @@ func (m *MsgMhfCreateGuild) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfCreateGuild) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfCreateGuild) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint8() bf.ReadUint16() // Zeroed
m.Unk1 = bf.ReadUint8() bf.ReadUint16() // Name length
_ = bf.ReadUint16() // len
m.Name = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes()) m.Name = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes())
return nil return nil
} }

View File

@@ -1,19 +1,19 @@
package mhfpacket package mhfpacket
import ( import (
"errors" "errors"
"erupe-ce/network/clientctx"
"erupe-ce/common/stringsupport"
"erupe-ce/network"
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
"erupe-ce/common/stringsupport"
"erupe-ce/network"
"erupe-ce/network/clientctx"
) )
// MsgMhfCreateJoint represents the MSG_MHF_CREATE_JOINT // MsgMhfCreateJoint represents the MSG_MHF_CREATE_JOINT
type MsgMhfCreateJoint struct { type MsgMhfCreateJoint struct {
AckHandle uint32 AckHandle uint32
GuildID uint32 GuildID uint32
Name string Name string
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -23,11 +23,12 @@ func (m *MsgMhfCreateJoint) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfCreateJoint) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfCreateJoint) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.GuildID = bf.ReadUint32() m.GuildID = bf.ReadUint32()
_ = bf.ReadUint32() // len bf.ReadUint16() // Zeroed
m.Name = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes()) bf.ReadUint16() // Name length
return nil m.Name = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes())
return nil
} }
// Build builds a binary packet from the current data. // Build builds a binary packet from the current data.

View File

@@ -1,15 +1,14 @@
package mhfpacket package mhfpacket
import ( import (
"errors"
"erupe-ce/common/byteframe"
"erupe-ce/network" "erupe-ce/network"
"erupe-ce/network/clientctx" "erupe-ce/network/clientctx"
"erupe-ce/common/byteframe"
) )
// MsgMhfDisplayedAchievement represents the MSG_MHF_DISPLAYED_ACHIEVEMENT // MsgMhfDisplayedAchievement represents the MSG_MHF_DISPLAYED_ACHIEVEMENT
type MsgMhfDisplayedAchievement struct { type MsgMhfDisplayedAchievement struct{}
Unk0 uint8
}
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
func (m *MsgMhfDisplayedAchievement) Opcode() network.PacketID { func (m *MsgMhfDisplayedAchievement) Opcode() network.PacketID {
@@ -18,12 +17,11 @@ func (m *MsgMhfDisplayedAchievement) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfDisplayedAchievement) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfDisplayedAchievement) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.Unk0 = bf.ReadUint8() bf.ReadUint8() // Zeroed
return nil return nil
} }
// Build builds a binary packet from the current data. // Build builds a binary packet from the current data.
func (m *MsgMhfDisplayedAchievement) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfDisplayedAchievement) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
bf.WriteUint8(m.Unk0) return errors.New("NOT IMPLEMENTED")
return nil
} }

View File

@@ -1,18 +1,18 @@
package mhfpacket 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"
) )
// MsgMhfEntryFesta represents the MSG_MHF_ENTRY_FESTA // MsgMhfEntryFesta represents the MSG_MHF_ENTRY_FESTA
type MsgMhfEntryFesta struct { type MsgMhfEntryFesta struct {
AckHandle uint32 AckHandle uint32
FestaID uint32 FestaID uint32
GuildID uint32 GuildID uint32
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -22,11 +22,11 @@ func (m *MsgMhfEntryFesta) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfEntryFesta) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfEntryFesta) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.FestaID = bf.ReadUint32() m.FestaID = bf.ReadUint32()
m.GuildID = bf.ReadUint32() m.GuildID = bf.ReadUint32()
_ = bf.ReadUint16() // Always 0 bf.ReadUint16() // Zeroed
return nil return nil
} }
// Build builds a binary packet from the current data. // Build builds a binary packet from the current data.

View File

@@ -1,17 +1,19 @@
package mhfpacket package mhfpacket
import ( import (
"errors"
"erupe-ce/common/byteframe"
"erupe-ce/network" "erupe-ce/network"
"erupe-ce/network/clientctx" "erupe-ce/network/clientctx"
"erupe-ce/common/byteframe"
) )
// MsgMhfEnumerateDistItem represents the MSG_MHF_ENUMERATE_DIST_ITEM // MsgMhfEnumerateDistItem represents the MSG_MHF_ENUMERATE_DIST_ITEM
type MsgMhfEnumerateDistItem struct { type MsgMhfEnumerateDistItem struct {
AckHandle uint32 AckHandle uint32
Unk0 uint8 DistType uint8
Unk1 uint16 Unk1 uint8
Unk2 uint16 Unk2 uint16
Unk3 []byte
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -22,17 +24,14 @@ func (m *MsgMhfEnumerateDistItem) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfEnumerateDistItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfEnumerateDistItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint8() m.DistType = bf.ReadUint8()
m.Unk1 = bf.ReadUint16() m.Unk1 = bf.ReadUint8()
m.Unk2 = bf.ReadUint16() m.Unk2 = bf.ReadUint16() // Maximum? Hardcoded to 256
m.Unk3 = bf.ReadBytes(uint(bf.ReadUint8()))
return nil return nil
} }
// Build builds a binary packet from the current data. // Build builds a binary packet from the current data.
func (m *MsgMhfEnumerateDistItem) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfEnumerateDistItem) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
bf.WriteUint32(m.AckHandle) return errors.New("NOT IMPLEMENTED")
bf.WriteUint8(m.Unk0)
bf.WriteUint16(m.Unk1)
bf.WriteUint16(m.Unk2)
return nil
} }

View File

@@ -1,16 +1,15 @@
package mhfpacket package mhfpacket
import ( import (
"errors"
"erupe-ce/common/byteframe"
"erupe-ce/network" "erupe-ce/network"
"erupe-ce/network/clientctx" "erupe-ce/network/clientctx"
"erupe-ce/common/byteframe"
) )
// MsgMhfEnumerateEvent represents the MSG_MHF_ENUMERATE_EVENT // MsgMhfEnumerateEvent represents the MSG_MHF_ENUMERATE_EVENT
type MsgMhfEnumerateEvent struct { type MsgMhfEnumerateEvent struct {
AckHandle uint32 AckHandle uint32
Unk0 uint16 // Hardcoded 0 in the binary
Unk1 uint16 // Hardcoded 0 in the binary
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -21,15 +20,12 @@ func (m *MsgMhfEnumerateEvent) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfEnumerateEvent) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfEnumerateEvent) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint16() bf.ReadUint16() // Zeroed
m.Unk1 = bf.ReadUint16() bf.ReadUint16() // Zeroed
return nil return nil
} }
// Build builds a binary packet from the current data. // Build builds a binary packet from the current data.
func (m *MsgMhfEnumerateEvent) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfEnumerateEvent) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
bf.WriteUint32(m.AckHandle) return errors.New("NOT IMPLEMENTED")
bf.WriteUint16(m.Unk0)
bf.WriteUint16(m.Unk1)
return nil
} }

View File

@@ -1,18 +1,18 @@
package mhfpacket 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"
) )
// MsgMhfEnumerateFestaMember represents the MSG_MHF_ENUMERATE_FESTA_MEMBER // MsgMhfEnumerateFestaMember represents the MSG_MHF_ENUMERATE_FESTA_MEMBER
type MsgMhfEnumerateFestaMember struct { type MsgMhfEnumerateFestaMember struct {
AckHandle uint32 AckHandle uint32
FestaID uint32 FestaID uint32
GuildID uint32 GuildID uint32
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -22,11 +22,11 @@ func (m *MsgMhfEnumerateFestaMember) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfEnumerateFestaMember) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfEnumerateFestaMember) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.FestaID = bf.ReadUint32() m.FestaID = bf.ReadUint32()
m.GuildID = bf.ReadUint32() m.GuildID = bf.ReadUint32()
_ = bf.ReadUint16() // Hardcoded 0 in the binary. bf.ReadUint16() // Zeroed
return nil return nil
} }
// Build builds a binary packet from the current data. // Build builds a binary packet from the current data.

View File

@@ -2,7 +2,6 @@ package mhfpacket
import ( import (
"errors" "errors"
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
"erupe-ce/network" "erupe-ce/network"
"erupe-ce/network/clientctx" "erupe-ce/network/clientctx"
@@ -11,9 +10,7 @@ import (
// MsgMhfEnumerateGuacot represents the MSG_MHF_ENUMERATE_GUACOT // MsgMhfEnumerateGuacot represents the MSG_MHF_ENUMERATE_GUACOT
type MsgMhfEnumerateGuacot struct { type MsgMhfEnumerateGuacot struct {
AckHandle uint32 AckHandle uint32
Unk0 uint16 // Hardcoded 0 in binary Unk0 uint32
Unk1 uint16 // Hardcoded 0 in binary
Unk2 uint16 // Hardcoded 0 in binary
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -24,9 +21,8 @@ func (m *MsgMhfEnumerateGuacot) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfEnumerateGuacot) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfEnumerateGuacot) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint16() m.Unk0 = bf.ReadUint32()
m.Unk1 = bf.ReadUint16() bf.ReadUint16() // Zeroed
m.Unk2 = bf.ReadUint16()
return nil return nil
} }

View File

@@ -2,9 +2,7 @@ package mhfpacket
import ( import (
"errors" "errors"
"erupe-ce/common/bfutil"
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
"erupe-ce/common/stringsupport"
"erupe-ce/network" "erupe-ce/network"
"erupe-ce/network/clientctx" "erupe-ce/network/clientctx"
) )
@@ -34,8 +32,8 @@ type MsgMhfEnumerateGuild struct {
Type EnumerateGuildType Type EnumerateGuildType
Page uint8 Page uint8
Sorting bool Sorting bool
Data1 []byte Data1 *byteframe.ByteFrame
Data2 string Data2 *byteframe.ByteFrame
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -49,12 +47,12 @@ func (m *MsgMhfEnumerateGuild) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Cli
m.Type = EnumerateGuildType(bf.ReadUint8()) m.Type = EnumerateGuildType(bf.ReadUint8())
m.Page = bf.ReadUint8() m.Page = bf.ReadUint8()
m.Sorting = bf.ReadBool() m.Sorting = bf.ReadBool()
_ = bf.ReadBytes(1) bf.ReadUint8() // Zeroed
m.Data1 = bf.ReadBytes(4) m.Data1 = byteframe.NewByteFrameFromBytes(bf.ReadBytes(4))
_ = bf.ReadBytes(2) bf.ReadUint16() // Zeroed
lenData2 := uint(bf.ReadUint8()) dataLen := uint(bf.ReadUint8())
_ = bf.ReadBytes(1) bf.ReadUint8() // Zeroed
m.Data2 = stringsupport.SJISToUTF8(bfutil.UpToNull(bf.ReadBytes(lenData2))) m.Data2 = byteframe.NewByteFrameFromBytes(bf.ReadBytes(dataLen))
return nil return nil
} }

View File

@@ -1,18 +1,17 @@
package mhfpacket 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"
) )
// MsgMhfEnumerateGuildItem represents the MSG_MHF_ENUMERATE_GUILD_ITEM // MsgMhfEnumerateGuildItem represents the MSG_MHF_ENUMERATE_GUILD_ITEM
type MsgMhfEnumerateGuildItem struct { type MsgMhfEnumerateGuildItem struct {
AckHandle uint32 AckHandle uint32
GuildId uint32 GuildID uint32
Unk0 uint16
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -22,9 +21,10 @@ func (m *MsgMhfEnumerateGuildItem) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfEnumerateGuildItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfEnumerateGuildItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.GuildId = bf.ReadUint32() m.GuildID = bf.ReadUint32()
m.Unk0 = bf.ReadUint16() bf.ReadUint8() // Zeroed
bf.ReadUint8() // Zeroed
return nil return nil
} }

View File

@@ -1,17 +1,17 @@
package mhfpacket package mhfpacket
import ( import (
"errors"
"erupe-ce/common/byteframe"
"erupe-ce/network" "erupe-ce/network"
"erupe-ce/network/clientctx" "erupe-ce/network/clientctx"
"erupe-ce/common/byteframe"
) )
// MsgMhfEnumerateGuildMember represents the MSG_MHF_ENUMERATE_GUILD_MEMBER // MsgMhfEnumerateGuildMember represents the MSG_MHF_ENUMERATE_GUILD_MEMBER
type MsgMhfEnumerateGuildMember struct { type MsgMhfEnumerateGuildMember struct {
AckHandle uint32 AckHandle uint32
Unk0 uint16 // Hardcoded 00 01 in the binary AllianceID uint32
Unk1 uint32 // Alliance related GuildID uint32
GuildID uint32
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -22,17 +22,14 @@ func (m *MsgMhfEnumerateGuildMember) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfEnumerateGuildMember) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfEnumerateGuildMember) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint16() bf.ReadUint8() // Zeroed
m.Unk1 = bf.ReadUint32() bf.ReadUint8() // Always 1
m.AllianceID = bf.ReadUint32()
m.GuildID = bf.ReadUint32() m.GuildID = bf.ReadUint32()
return nil return nil
} }
// Build builds a binary packet from the current data. // Build builds a binary packet from the current data.
func (m *MsgMhfEnumerateGuildMember) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfEnumerateGuildMember) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
bf.WriteUint32(m.AckHandle) return errors.New("NOT IMPLEMENTED")
bf.WriteUint16(m.Unk0)
bf.WriteUint32(m.Unk1)
bf.WriteUint32(m.GuildID)
return nil
} }

View File

@@ -12,7 +12,8 @@ import (
type MsgMhfEnumerateGuildTresure struct { type MsgMhfEnumerateGuildTresure struct {
AckHandle uint32 AckHandle uint32
MaxHunts uint16 MaxHunts uint16
Unk uint32 Unk0 uint16
Unk1 uint16
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -24,9 +25,8 @@ func (m *MsgMhfEnumerateGuildTresure) Opcode() network.PacketID {
func (m *MsgMhfEnumerateGuildTresure) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfEnumerateGuildTresure) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.MaxHunts = bf.ReadUint16() m.MaxHunts = bf.ReadUint16()
// Changes with MaxHunts m.Unk0 = bf.ReadUint16()
// 0 if MaxHunts = 1, 1 if MaxHunts = 30 m.Unk1 = bf.ReadUint16()
m.Unk = bf.ReadUint32()
return nil return nil
} }

View File

@@ -14,7 +14,6 @@ type MsgMhfEnumerateHouse struct {
AckHandle uint32 AckHandle uint32
CharID uint32 CharID uint32
Method uint8 Method uint8
Unk uint16
Name string Name string
} }
@@ -28,7 +27,7 @@ func (m *MsgMhfEnumerateHouse) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Cli
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.CharID = bf.ReadUint32() m.CharID = bf.ReadUint32()
m.Method = bf.ReadUint8() m.Method = bf.ReadUint8()
m.Unk = bf.ReadUint16() bf.ReadUint16() // Zeroed
lenName := bf.ReadUint8() lenName := bf.ReadUint8()
if lenName > 0 { if lenName > 0 {
m.Name = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes()) m.Name = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes())

View File

@@ -10,8 +10,13 @@ import (
// MsgMhfEnumerateInvGuild represents the MSG_MHF_ENUMERATE_INV_GUILD // MsgMhfEnumerateInvGuild represents the MSG_MHF_ENUMERATE_INV_GUILD
type MsgMhfEnumerateInvGuild struct { type MsgMhfEnumerateInvGuild struct {
AckHandle uint32 AckHandle uint32
Unk []byte Unk uint32
Operation uint8
ActiveHours uint8
DaysActive uint8
PlayStyle uint8
GuildRequest uint8
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -22,7 +27,12 @@ func (m *MsgMhfEnumerateInvGuild) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfEnumerateInvGuild) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfEnumerateInvGuild) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk = bf.ReadBytes(9) m.Unk = bf.ReadUint32()
m.Operation = bf.ReadUint8()
m.ActiveHours = bf.ReadUint8()
m.DaysActive = bf.ReadUint8()
m.PlayStyle = bf.ReadUint8()
m.GuildRequest = bf.ReadUint8()
return nil return nil
} }

View File

@@ -1,18 +1,16 @@
package mhfpacket 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"
) )
// MsgMhfEnumeratePrice represents the MSG_MHF_ENUMERATE_PRICE // MsgMhfEnumeratePrice represents the MSG_MHF_ENUMERATE_PRICE
type MsgMhfEnumeratePrice struct { type MsgMhfEnumeratePrice struct {
AckHandle uint32 AckHandle uint32
Unk0 uint16 // Hardcoded 0 in the binary
Unk1 uint16 // Hardcoded 0 in the binary
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -23,8 +21,8 @@ func (m *MsgMhfEnumeratePrice) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfEnumeratePrice) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfEnumeratePrice) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint16() bf.ReadUint16() // Zeroed
m.Unk1 = bf.ReadUint16() bf.ReadUint16() // Zeroed
return nil return nil
} }

View File

@@ -1,18 +1,16 @@
package mhfpacket 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"
) )
// MsgMhfEnumerateRanking represents the MSG_MHF_ENUMERATE_RANKING // MsgMhfEnumerateRanking represents the MSG_MHF_ENUMERATE_RANKING
type MsgMhfEnumerateRanking struct { type MsgMhfEnumerateRanking struct {
AckHandle uint32 AckHandle uint32
Unk0 uint16 // Hardcoded 0 in the binary
Unk1 uint16 // Hardcoded 0 in the binary
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -23,8 +21,9 @@ func (m *MsgMhfEnumerateRanking) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfEnumerateRanking) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfEnumerateRanking) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint16() bf.ReadUint16() // Zeroed
m.Unk1 = bf.ReadUint16() bf.ReadUint8() // Zeroed
bf.ReadUint8() // Zeroed
return nil return nil
} }

View File

@@ -11,7 +11,6 @@ import (
// MsgMhfEnumerateUnionItem represents the MSG_MHF_ENUMERATE_UNION_ITEM // MsgMhfEnumerateUnionItem represents the MSG_MHF_ENUMERATE_UNION_ITEM
type MsgMhfEnumerateUnionItem struct { type MsgMhfEnumerateUnionItem struct {
AckHandle uint32 AckHandle uint32
Unk0 uint16
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -22,8 +21,8 @@ func (m *MsgMhfEnumerateUnionItem) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfEnumerateUnionItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfEnumerateUnionItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint16() bf.ReadUint8() // Zeroed
bf.ReadUint8() // Zeroed
return nil return nil
} }

View File

@@ -13,7 +13,6 @@ type MsgMhfExchangeWeeklyStamp struct {
AckHandle uint32 AckHandle uint32
StampType string StampType string
Unk1 uint8 Unk1 uint8
Unk2 uint16
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -32,7 +31,7 @@ func (m *MsgMhfExchangeWeeklyStamp) Parse(bf *byteframe.ByteFrame, ctx *clientct
m.StampType = "ex" m.StampType = "ex"
} }
m.Unk1 = bf.ReadUint8() m.Unk1 = bf.ReadUint8()
m.Unk2 = bf.ReadUint16() bf.ReadUint16() // Zeroed
return nil return nil
} }

View File

@@ -12,7 +12,6 @@ import (
type MsgMhfGetAchievement struct { type MsgMhfGetAchievement struct {
AckHandle uint32 AckHandle uint32
CharID uint32 CharID uint32
Unk1 uint32 // char?
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -24,7 +23,7 @@ func (m *MsgMhfGetAchievement) Opcode() network.PacketID {
func (m *MsgMhfGetAchievement) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfGetAchievement) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.CharID = bf.ReadUint32() m.CharID = bf.ReadUint32()
m.Unk1 = bf.ReadUint32() bf.ReadUint32() // Zeroed
return nil return nil
} }

View File

@@ -1,17 +1,16 @@
package mhfpacket 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"
) )
// MsgMhfGetRengokuBinary represents the MSG_MHF_GET_RENGOKU_BINARY // MsgMhfGetRengokuBinary represents the MSG_MHF_GET_RENGOKU_BINARY
type MsgMhfGetRengokuBinary struct { type MsgMhfGetRengokuBinary struct {
AckHandle uint32 AckHandle uint32
Unk0 uint8 // Hardcoded 0 in binary
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -22,7 +21,7 @@ func (m *MsgMhfGetRengokuBinary) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfGetRengokuBinary) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfGetRengokuBinary) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint8() bf.ReadUint8() // Zeroed
return nil return nil
} }

View File

@@ -1,18 +1,17 @@
package mhfpacket 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"
) )
// MsgMhfInfoFesta represents the MSG_MHF_INFO_FESTA // MsgMhfInfoFesta represents the MSG_MHF_INFO_FESTA
type MsgMhfInfoFesta struct { type MsgMhfInfoFesta struct {
AckHandle uint32 AckHandle uint32
Unk0 uint16 // Hardcoded 0 in the binary Unk0 uint8
Unk1 uint16 // Hardcoded 0 in the binary
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -23,8 +22,10 @@ func (m *MsgMhfInfoFesta) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfInfoFesta) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfInfoFesta) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint16() m.Unk0 = bf.ReadUint8()
m.Unk1 = bf.ReadUint16() bf.ReadUint8() // Zeroed
bf.ReadUint8() // Zeroed
bf.ReadUint8() // Zeroed
return nil return nil
} }

View File

@@ -12,7 +12,6 @@ import (
type MsgMhfInfoJoint struct { type MsgMhfInfoJoint struct {
AckHandle uint32 AckHandle uint32
AllianceID uint32 AllianceID uint32
Unk uint32
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -24,7 +23,7 @@ func (m *MsgMhfInfoJoint) Opcode() network.PacketID {
func (m *MsgMhfInfoJoint) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfInfoJoint) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.AllianceID = bf.ReadUint32() m.AllianceID = bf.ReadUint32()
m.Unk = bf.ReadUint32() bf.ReadUint32() // Zeroed
return nil return nil
} }

View File

@@ -1,17 +1,16 @@
package mhfpacket 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"
) )
// MsgMhfListMail represents the MSG_MHF_LIST_MAIL // MsgMhfListMail represents the MSG_MHF_LIST_MAIL
type MsgMhfListMail struct { type MsgMhfListMail struct {
AckHandle uint32 AckHandle uint32
Unk0 uint32
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -22,7 +21,8 @@ func (m *MsgMhfListMail) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfListMail) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfListMail) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint32() bf.ReadUint16() // Zeroed
bf.ReadUint16() // Zeroed
return nil return nil
} }

View File

@@ -1,17 +1,17 @@
package mhfpacket 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"
) )
// MsgMhfListMember represents the MSG_MHF_LIST_MEMBER // MsgMhfListMember represents the MSG_MHF_LIST_MEMBER
type MsgMhfListMember struct { type MsgMhfListMember struct {
AckHandle uint32 AckHandle uint32
Unk0 uint16 // Hardcoded 01 00 in the JP client. Unk0 uint8 // Hardcoded 01 in the JP client.
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -22,7 +22,8 @@ func (m *MsgMhfListMember) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfListMember) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfListMember) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint16() m.Unk0 = bf.ReadUint8()
bf.ReadUint8() // Zeroed
return nil return nil
} }

View File

@@ -1,17 +1,17 @@
package mhfpacket 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"
) )
// MsgMhfLoadGuildCooking represents the MSG_MHF_LOAD_GUILD_COOKING // MsgMhfLoadGuildCooking represents the MSG_MHF_LOAD_GUILD_COOKING
type MsgMhfLoadGuildCooking struct{ type MsgMhfLoadGuildCooking struct {
AckHandle uint32 AckHandle uint32
MaxMeals uint8 MaxMeals uint8
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -22,7 +22,7 @@ func (m *MsgMhfLoadGuildCooking) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfLoadGuildCooking) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfLoadGuildCooking) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
_ = bf.ReadUint8() m.MaxMeals = bf.ReadUint8()
return nil return nil
} }

View File

@@ -16,7 +16,6 @@ type MsgMhfLoadHouse struct {
Destination uint8 Destination uint8
// False if already in hosts My Series, in case host updates PW // False if already in hosts My Series, in case host updates PW
CheckPass bool CheckPass bool
Unk3 uint16 // Hardcoded 0 in binary
Password string Password string
} }
@@ -31,8 +30,8 @@ func (m *MsgMhfLoadHouse) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientCo
m.CharID = bf.ReadUint32() m.CharID = bf.ReadUint32()
m.Destination = bf.ReadUint8() m.Destination = bf.ReadUint8()
m.CheckPass = bf.ReadBool() m.CheckPass = bf.ReadBool()
_ = bf.ReadUint16() bf.ReadUint16() // Zeroed
_ = bf.ReadUint8() // Password length bf.ReadUint8() // Password length
m.Password = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes()) m.Password = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes())
return nil return nil
} }

View File

@@ -23,7 +23,6 @@ type MsgMhfOperateGuildMember struct {
GuildID uint32 GuildID uint32
CharID uint32 CharID uint32
Action uint8 Action uint8
Unk []byte
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -37,7 +36,8 @@ func (m *MsgMhfOperateGuildMember) Parse(bf *byteframe.ByteFrame, ctx *clientctx
m.GuildID = bf.ReadUint32() m.GuildID = bf.ReadUint32()
m.CharID = bf.ReadUint32() m.CharID = bf.ReadUint32()
m.Action = bf.ReadUint8() m.Action = bf.ReadUint8()
m.Unk = bf.ReadBytes(3) bf.ReadUint8() // Zeroed
bf.ReadUint16() // Zeroed
return nil return nil
} }

View File

@@ -22,7 +22,8 @@ type MsgMhfOperateJoint struct {
AllianceID uint32 AllianceID uint32
GuildID uint32 GuildID uint32
Action OperateJointAction Action OperateJointAction
UnkData *byteframe.ByteFrame Data1 *byteframe.ByteFrame
Data2 *byteframe.ByteFrame
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -36,8 +37,9 @@ 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 = byteframe.NewByteFrameFromBytes(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
} }

View File

@@ -1,20 +1,20 @@
package mhfpacket 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"
) )
// MsgMhfOprMember represents the MSG_MHF_OPR_MEMBER // MsgMhfOprMember represents the MSG_MHF_OPR_MEMBER
type MsgMhfOprMember struct { type MsgMhfOprMember struct {
AckHandle uint32 AckHandle uint32
Blacklist bool Blacklist bool
Operation bool Operation bool
Unk uint16 Unk uint16
CharID uint32 CharIDs []uint32
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -24,12 +24,15 @@ func (m *MsgMhfOprMember) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfOprMember) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfOprMember) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Blacklist = bf.ReadBool() m.Blacklist = bf.ReadBool()
m.Operation = bf.ReadBool() m.Operation = bf.ReadBool()
m.Unk = bf.ReadUint16() bf.ReadUint8()
m.CharID = bf.ReadUint32() chars := int(bf.ReadUint8())
return nil for i := 0; i < chars; i++ {
m.CharIDs = append(m.CharIDs, bf.ReadUint32())
}
return nil
} }
// Build builds a binary packet from the current data. // Build builds a binary packet from the current data.

View File

@@ -11,10 +11,11 @@ import (
type OperateMailOperation uint8 type OperateMailOperation uint8
const ( const (
OPERATE_MAIL_DELETE = 0x01 OperateMailDelete = iota + 1
OPERATE_MAIL_LOCK = 0x02 OperateMailLock
OPERATE_MAIL_UNLOCK = 0x03 OperateMailUnlock
OPERATE_MAIL_ACQUIRE_ITEM = 0x05 OpreateMailNull
OperateMailAcquireItem
) )
// MsgMhfOprtMail represents the MSG_MHF_OPRT_MAIL // MsgMhfOprtMail represents the MSG_MHF_OPRT_MAIL
@@ -23,7 +24,6 @@ type MsgMhfOprtMail struct {
AccIndex uint8 AccIndex uint8
Index uint8 Index uint8
Operation OperateMailOperation Operation OperateMailOperation
Unk0 uint8
Data []byte Data []byte
Amount uint16 Amount uint16
ItemID uint16 ItemID uint16
@@ -40,8 +40,8 @@ func (m *MsgMhfOprtMail) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientCon
m.AccIndex = bf.ReadUint8() m.AccIndex = bf.ReadUint8()
m.Index = bf.ReadUint8() m.Index = bf.ReadUint8()
m.Operation = OperateMailOperation(bf.ReadUint8()) m.Operation = OperateMailOperation(bf.ReadUint8())
m.Unk0 = bf.ReadUint8() bf.ReadUint8() // Zeroed
if m.Operation == OPERATE_MAIL_ACQUIRE_ITEM { if m.Operation == OperateMailAcquireItem {
m.Amount = bf.ReadUint16() m.Amount = bf.ReadUint16()
m.ItemID = bf.ReadUint16() m.ItemID = bf.ReadUint16()
} }

View File

@@ -19,7 +19,6 @@ type MsgMhfReadMail struct {
// This is the index within the current mail list // This is the index within the current mail list
Index uint8 Index uint8
Unk0 uint16
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -32,7 +31,7 @@ func (m *MsgMhfReadMail) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientCon
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.AccIndex = bf.ReadUint8() m.AccIndex = bf.ReadUint8()
m.Index = bf.ReadUint8() m.Index = bf.ReadUint8()
m.Unk0 = bf.ReadUint16() bf.ReadUint16() // Zeroed
return nil return nil
} }

View File

@@ -13,7 +13,6 @@ type MsgMhfReadMercenaryW struct {
AckHandle uint32 AckHandle uint32
Op uint8 Op uint8
Unk1 uint8 Unk1 uint8
Unk2 uint16 // Hardcoded 0 in the binary
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -25,8 +24,9 @@ func (m *MsgMhfReadMercenaryW) Opcode() network.PacketID {
func (m *MsgMhfReadMercenaryW) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfReadMercenaryW) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Op = bf.ReadUint8() m.Op = bf.ReadUint8()
m.Unk1 = bf.ReadUint8() m.Unk1 = bf.ReadUint8() // Supposed to be 0 or 1, but always 1
m.Unk2 = bf.ReadUint16() bf.ReadUint8() // Zeroed
bf.ReadUint8() // Zeroed
return nil return nil
} }

View File

@@ -1,20 +1,18 @@
package mhfpacket package mhfpacket
import ( import (
"erupe-ce/common/byteframe"
"erupe-ce/network" "erupe-ce/network"
"erupe-ce/network/clientctx" "erupe-ce/network/clientctx"
"erupe-ce/common/byteframe"
) )
// MsgMhfRegisterEvent represents the MSG_MHF_REGISTER_EVENT // MsgMhfRegisterEvent represents the MSG_MHF_REGISTER_EVENT
type MsgMhfRegisterEvent struct { type MsgMhfRegisterEvent struct {
AckHandle uint32 AckHandle uint32
Unk0 uint16 Unk0 uint16
Unk1 uint8 WorldID uint16
Unk2 uint8 LandID uint16
Unk3 uint8 Unk1 bool
Unk4 uint8
Unk5 uint16
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -26,11 +24,10 @@ func (m *MsgMhfRegisterEvent) Opcode() network.PacketID {
func (m *MsgMhfRegisterEvent) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfRegisterEvent) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint16() m.Unk0 = bf.ReadUint16()
m.Unk1 = bf.ReadUint8() m.WorldID = bf.ReadUint16()
m.Unk2 = bf.ReadUint8() m.LandID = bf.ReadUint16()
m.Unk3 = bf.ReadUint8() m.Unk1 = bf.ReadBool()
m.Unk4 = bf.ReadUint8() bf.ReadUint8() // Zeroed
m.Unk5 = bf.ReadUint16()
return nil return nil
} }

View File

@@ -11,8 +11,7 @@ import (
// MsgMhfReleaseEvent represents the MSG_MHF_RELEASE_EVENT // MsgMhfReleaseEvent represents the MSG_MHF_RELEASE_EVENT
type MsgMhfReleaseEvent struct { type MsgMhfReleaseEvent struct {
AckHandle uint32 AckHandle uint32
Unk0 uint32 RaviID uint32
Unk1 uint32
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -23,8 +22,8 @@ func (m *MsgMhfReleaseEvent) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfReleaseEvent) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfReleaseEvent) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint32() m.RaviID = bf.ReadUint32()
m.Unk1 = bf.ReadUint32() bf.ReadUint32() // Zeroed
return nil return nil
} }

View File

@@ -15,7 +15,7 @@ type MsgMhfSendMail struct {
RecipientID uint32 RecipientID uint32
SubjectLength uint16 SubjectLength uint16
BodyLength uint16 BodyLength uint16
Quantity uint32 Quantity uint16
ItemID uint16 ItemID uint16
Subject string Subject string
Body string Body string
@@ -32,7 +32,8 @@ func (m *MsgMhfSendMail) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientCon
m.RecipientID = bf.ReadUint32() m.RecipientID = bf.ReadUint32()
m.SubjectLength = bf.ReadUint16() m.SubjectLength = bf.ReadUint16()
m.BodyLength = bf.ReadUint16() m.BodyLength = bf.ReadUint16()
m.Quantity = bf.ReadUint32() bf.ReadUint16() // Zeroed
m.Quantity = bf.ReadUint16()
m.ItemID = bf.ReadUint16() m.ItemID = bf.ReadUint16()
m.Subject = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes()) m.Subject = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes())
m.Body = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes()) m.Body = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes())

View File

@@ -13,7 +13,6 @@ type MsgMhfSetGuildManageRight struct {
AckHandle uint32 AckHandle uint32
CharID uint32 CharID uint32
Allowed bool Allowed bool
Unk []byte
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -26,7 +25,7 @@ func (m *MsgMhfSetGuildManageRight) Parse(bf *byteframe.ByteFrame, ctx *clientct
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.CharID = bf.ReadUint32() m.CharID = bf.ReadUint32()
m.Allowed = bf.ReadBool() m.Allowed = bf.ReadBool()
m.Unk = bf.ReadBytes(3) bf.ReadBytes(3) // Zeroed
return nil return nil
} }

View File

@@ -34,7 +34,7 @@ func (m *MsgMhfStampcardStamp) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Cli
m.HR = bf.ReadUint16() m.HR = bf.ReadUint16()
m.GR = bf.ReadUint16() m.GR = bf.ReadUint16()
m.Stamps = bf.ReadUint16() m.Stamps = bf.ReadUint16()
_ = bf.ReadUint16() bf.ReadUint16() // Zeroed
if _config.ErupeConfig.RealClientMode > _config.Z1 { if _config.ErupeConfig.RealClientMode > _config.Z1 {
m.Reward1 = uint16(bf.ReadUint32()) m.Reward1 = uint16(bf.ReadUint32())
m.Reward2 = uint16(bf.ReadUint32()) m.Reward2 = uint16(bf.ReadUint32())

View File

@@ -1,18 +1,18 @@
package mhfpacket 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"
) )
// MsgMhfStateFestaG represents the MSG_MHF_STATE_FESTA_G // MsgMhfStateFestaG represents the MSG_MHF_STATE_FESTA_G
type MsgMhfStateFestaG struct { type MsgMhfStateFestaG struct {
AckHandle uint32 AckHandle uint32
FestaID uint32 FestaID uint32
GuildID uint32 GuildID uint32
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -25,7 +25,7 @@ func (m *MsgMhfStateFestaG) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Client
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.FestaID = bf.ReadUint32() m.FestaID = bf.ReadUint32()
m.GuildID = bf.ReadUint32() m.GuildID = bf.ReadUint32()
_ = bf.ReadUint16() // Hardcoded 0 in the binary. bf.ReadUint16() // Zeroed
return nil return nil
} }

View File

@@ -1,18 +1,18 @@
package mhfpacket 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"
) )
// MsgMhfStateFestaU represents the MSG_MHF_STATE_FESTA_U // MsgMhfStateFestaU represents the MSG_MHF_STATE_FESTA_U
type MsgMhfStateFestaU struct { type MsgMhfStateFestaU struct {
AckHandle uint32 AckHandle uint32
FestaID uint32 FestaID uint32
GuildID uint32 GuildID uint32
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -22,11 +22,11 @@ func (m *MsgMhfStateFestaU) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfStateFestaU) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfStateFestaU) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.FestaID = bf.ReadUint32() m.FestaID = bf.ReadUint32()
m.GuildID = bf.ReadUint32() m.GuildID = bf.ReadUint32()
_ = bf.ReadUint16() // Hardcoded 0 in the binary. bf.ReadUint16() // Zeroed
return nil return nil
} }
// Build builds a binary packet from the current data. // Build builds a binary packet from the current data.

View File

@@ -1,11 +1,11 @@
package mhfpacket 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"
) )
// MsgMhfTransferItem represents the MSG_MHF_TRANSFER_ITEM // MsgMhfTransferItem represents the MSG_MHF_TRANSFER_ITEM
@@ -15,8 +15,8 @@ type MsgMhfTransferItem struct {
// correlate with any item IDs that would make sense to get after quests so // correlate with any item IDs that would make sense to get after quests so
// I have no idea what this actually does // I have no idea what this actually does
Unk0 uint32 Unk0 uint32
Unk1 uint16 // Hardcoded Unk1 uint8
Unk2 uint16 // Hardcoded Unk2 uint16
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -28,7 +28,8 @@ func (m *MsgMhfTransferItem) Opcode() network.PacketID {
func (m *MsgMhfTransferItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfTransferItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint32() m.Unk0 = bf.ReadUint32()
m.Unk1 = bf.ReadUint16() m.Unk1 = bf.ReadUint8()
bf.ReadUint8() // Zeroed
m.Unk2 = bf.ReadUint16() m.Unk2 = bf.ReadUint16()
return nil return nil
} }

View File

@@ -12,7 +12,6 @@ import (
type MsgMhfTransitMessage struct { type MsgMhfTransitMessage struct {
AckHandle uint32 AckHandle uint32
Unk0 uint8 Unk0 uint8
Unk1 uint8
SearchType uint16 SearchType uint16
MessageData []byte MessageData []byte
} }
@@ -26,7 +25,7 @@ func (m *MsgMhfTransitMessage) Opcode() network.PacketID {
func (m *MsgMhfTransitMessage) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfTransitMessage) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint8() m.Unk0 = bf.ReadUint8()
m.Unk1 = bf.ReadUint8() bf.ReadUint8() // Zeroed
m.SearchType = bf.ReadUint16() m.SearchType = bf.ReadUint16()
m.MessageData = bf.ReadBytes(uint(bf.ReadUint16())) m.MessageData = bf.ReadBytes(uint(bf.ReadUint16()))
return nil return nil

View File

@@ -1,18 +1,16 @@
package mhfpacket 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"
) )
// MsgMhfUpdateCafepoint represents the MSG_MHF_UPDATE_CAFEPOINT // MsgMhfUpdateCafepoint represents the MSG_MHF_UPDATE_CAFEPOINT
type MsgMhfUpdateCafepoint struct { type MsgMhfUpdateCafepoint struct {
AckHandle uint32 AckHandle uint32
Unk0 uint16 // Hardcoded 0 in binary
Unk1 uint16 // Hardcoded 0 in binary
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -23,8 +21,8 @@ func (m *MsgMhfUpdateCafepoint) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfUpdateCafepoint) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfUpdateCafepoint) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint16() bf.ReadUint16() // Zeroed
m.Unk1 = bf.ReadUint16() bf.ReadUint16() // Zeroed
return nil return nil
} }

View File

@@ -2,27 +2,23 @@ package mhfpacket
import ( import (
"errors" "errors"
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
"erupe-ce/network" "erupe-ce/network"
"erupe-ce/network/clientctx" "erupe-ce/network/clientctx"
) )
type Gook struct { type Goocoo struct {
Exists bool Index uint32
Index uint32 Data1 []uint16
Type uint16 Data2 []uint32
Data []byte Name []byte
NameLen uint8
Name []byte
} }
// MsgMhfUpdateGuacot represents the MSG_MHF_UPDATE_GUACOT // MsgMhfUpdateGuacot represents the MSG_MHF_UPDATE_GUACOT
type MsgMhfUpdateGuacot struct { type MsgMhfUpdateGuacot struct {
AckHandle uint32 AckHandle uint32
EntryCount uint16 EntryCount uint16
Unk0 uint16 // Hardcoded 0 in binary Goocoos []Goocoo
Gooks []Gook
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -34,20 +30,18 @@ func (m *MsgMhfUpdateGuacot) Opcode() network.PacketID {
func (m *MsgMhfUpdateGuacot) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfUpdateGuacot) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.EntryCount = bf.ReadUint16() m.EntryCount = bf.ReadUint16()
m.Unk0 = bf.ReadUint16() bf.ReadUint16() // Zeroed
var temp Goocoo
for i := 0; i < int(m.EntryCount); i++ { for i := 0; i < int(m.EntryCount); i++ {
e := Gook{} temp.Index = bf.ReadUint32()
e.Index = bf.ReadUint32() for j := 0; j < 22; j++ {
e.Type = bf.ReadUint16() temp.Data1 = append(temp.Data1, bf.ReadUint16())
e.Data = bf.ReadBytes(50)
e.NameLen = bf.ReadUint8()
e.Name = bf.ReadBytes(uint(e.NameLen))
if e.Type > 0 {
e.Exists = true
} else {
e.Exists = false
} }
m.Gooks = append(m.Gooks, e) for j := 0; j < 2; j++ {
temp.Data2 = append(temp.Data2, bf.ReadUint32())
}
temp.Name = bf.ReadBytes(uint(bf.ReadUint8()))
m.Goocoos = append(m.Goocoos, temp)
} }
return nil return nil
} }

View File

@@ -25,8 +25,6 @@ type GuildIconMsgPart struct {
type MsgMhfUpdateGuildIcon struct { type MsgMhfUpdateGuildIcon struct {
AckHandle uint32 AckHandle uint32
GuildID uint32 GuildID uint32
PartCount uint16
Unk1 uint16
IconParts []GuildIconMsgPart IconParts []GuildIconMsgPart
} }
@@ -39,12 +37,12 @@ func (m *MsgMhfUpdateGuildIcon) Opcode() network.PacketID {
func (m *MsgMhfUpdateGuildIcon) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfUpdateGuildIcon) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.GuildID = bf.ReadUint32() m.GuildID = bf.ReadUint32()
m.PartCount = bf.ReadUint16() partCount := int(bf.ReadUint16())
m.Unk1 = bf.ReadUint16() bf.ReadUint8() // Zeroed
bf.ReadUint8() // Zeroed
m.IconParts = make([]GuildIconMsgPart, partCount)
m.IconParts = make([]GuildIconMsgPart, m.PartCount) for i := 0; i < partCount; i++ {
for i := 0; i < int(m.PartCount); i++ {
m.IconParts[i] = GuildIconMsgPart{ m.IconParts[i] = GuildIconMsgPart{
Index: bf.ReadUint16(), Index: bf.ReadUint16(),
ID: bf.ReadUint16(), ID: bf.ReadUint16(),

View File

@@ -10,7 +10,7 @@ import (
type Item struct { type Item struct {
Unk0 uint32 Unk0 uint32
ItemId uint16 ItemID uint16
Amount uint16 Amount uint16
Unk1 uint32 Unk1 uint32
} }
@@ -18,10 +18,8 @@ type Item struct {
// MsgMhfUpdateGuildItem represents the MSG_MHF_UPDATE_GUILD_ITEM // MsgMhfUpdateGuildItem represents the MSG_MHF_UPDATE_GUILD_ITEM
type MsgMhfUpdateGuildItem struct { type MsgMhfUpdateGuildItem struct {
AckHandle uint32 AckHandle uint32
GuildId uint32 GuildID uint32
Amount uint16 Items []Item
Unk1 uint16 // 0x00 0x00
Items []Item // Array of updated item IDs
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -32,14 +30,15 @@ func (m *MsgMhfUpdateGuildItem) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfUpdateGuildItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfUpdateGuildItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.GuildId = bf.ReadUint32() m.GuildID = bf.ReadUint32()
m.Amount = bf.ReadUint16() itemCount := int(bf.ReadUint16())
m.Unk1 = bf.ReadUint16() bf.ReadUint8() // Zeroed
m.Items = make([]Item, int(m.Amount)) bf.ReadUint8() // Zeroed
m.Items = make([]Item, itemCount)
for i := 0; i < int(m.Amount); i++ { for i := 0; i < itemCount; i++ {
m.Items[i].Unk0 = bf.ReadUint32() m.Items[i].Unk0 = bf.ReadUint32()
m.Items[i].ItemId = bf.ReadUint16() m.Items[i].ItemID = bf.ReadUint16()
m.Items[i].Amount = bf.ReadUint16() m.Items[i].Amount = bf.ReadUint16()
m.Items[i].Unk1 = bf.ReadUint32() m.Items[i].Unk1 = bf.ReadUint32()
} }

View File

@@ -13,8 +13,7 @@ import (
type MsgMhfUpdateHouse struct { type MsgMhfUpdateHouse struct {
AckHandle uint32 AckHandle uint32
State uint8 State uint8
Unk1 uint8 // Always 0x01 Unk1 uint8 // Always 0x01
Unk2 uint16 // Always 0x0000
Password string Password string
} }
@@ -28,8 +27,9 @@ func (m *MsgMhfUpdateHouse) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Client
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.State = bf.ReadUint8() m.State = bf.ReadUint8()
m.Unk1 = bf.ReadUint8() m.Unk1 = bf.ReadUint8()
m.Unk2 = bf.ReadUint16() bf.ReadUint8() // Zeroed
_ = bf.ReadUint8() // Password length bf.ReadUint8() // Zeroed
bf.ReadUint8() // Password length
m.Password = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes()) m.Password = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes())
return nil return nil
} }

View File

@@ -1,17 +1,18 @@
package mhfpacket package mhfpacket
import ( import (
"errors" "errors"
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
_config "erupe-ce/config"
"erupe-ce/network"
"erupe-ce/network/clientctx"
) )
// MsgMhfUpdateMyhouseInfo represents the MSG_MHF_UPDATE_MYHOUSE_INFO // MsgMhfUpdateMyhouseInfo represents the MSG_MHF_UPDATE_MYHOUSE_INFO
type MsgMhfUpdateMyhouseInfo struct { type MsgMhfUpdateMyhouseInfo struct {
AckHandle uint32 AckHandle uint32
Unk0 []byte Data []byte
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -22,7 +23,16 @@ func (m *MsgMhfUpdateMyhouseInfo) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfUpdateMyhouseInfo) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfUpdateMyhouseInfo) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadBytes(0x16A) if _config.ErupeConfig.RealClientMode >= _config.G10 {
m.Data = bf.ReadBytes(362)
} else if _config.ErupeConfig.RealClientMode >= _config.GG {
m.Data = bf.ReadBytes(338)
} else if _config.ErupeConfig.RealClientMode >= _config.F5 {
// G1 is a guess
m.Data = bf.ReadBytes(314)
} else {
m.Data = bf.ReadBytes(290)
}
return nil return nil
} }

View File

@@ -11,9 +11,7 @@ import (
// MsgMhfUpdateUnionItem represents the MSG_MHF_UPDATE_UNION_ITEM // MsgMhfUpdateUnionItem represents the MSG_MHF_UPDATE_UNION_ITEM
type MsgMhfUpdateUnionItem struct { type MsgMhfUpdateUnionItem struct {
AckHandle uint32 AckHandle uint32
Amount uint16 Items []Item
Unk1 uint16 // 0x00 0x00
Items []Item // Array of updated item IDs
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -24,13 +22,14 @@ func (m *MsgMhfUpdateUnionItem) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfUpdateUnionItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfUpdateUnionItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Amount = bf.ReadUint16() itemCount := int(bf.ReadUint16())
m.Unk1 = bf.ReadUint16() bf.ReadUint8() // Zeroed
m.Items = make([]Item, int(m.Amount)) bf.ReadUint8() // Zeroed
m.Items = make([]Item, itemCount)
for i := 0; i < int(m.Amount); i++ { for i := 0; i < itemCount; i++ {
m.Items[i].Unk0 = bf.ReadUint32() m.Items[i].Unk0 = bf.ReadUint32()
m.Items[i].ItemId = bf.ReadUint16() m.Items[i].ItemID = bf.ReadUint16()
m.Items[i].Amount = bf.ReadUint16() m.Items[i].Amount = bf.ReadUint16()
m.Items[i].Unk1 = bf.ReadUint32() m.Items[i].Unk1 = bf.ReadUint32()
} }

View File

@@ -1,19 +1,20 @@
package mhfpacket 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"
) )
// MsgMhfUseGachaPoint represents the MSG_MHF_USE_GACHA_POINT // MsgMhfUseGachaPoint represents the MSG_MHF_USE_GACHA_POINT
type MsgMhfUseGachaPoint struct{ type MsgMhfUseGachaPoint struct {
AckHandle uint32 AckHandle uint32
Unk0 uint16 // padding? Unk0 uint8
TrialCoins uint32 Unk1 uint8
PremiumCoins uint32 TrialCoins uint32
PremiumCoins uint32
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -24,7 +25,8 @@ func (m *MsgMhfUseGachaPoint) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfUseGachaPoint) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfUseGachaPoint) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint16() m.Unk0 = bf.ReadUint8()
m.Unk1 = bf.ReadUint8()
m.TrialCoins = bf.ReadUint32() m.TrialCoins = bf.ReadUint32()
m.PremiumCoins = bf.ReadUint32() m.PremiumCoins = bf.ReadUint32()
return nil return nil

View File

@@ -11,7 +11,7 @@ import (
// MsgMhfVoteFesta represents the MSG_MHF_VOTE_FESTA // MsgMhfVoteFesta represents the MSG_MHF_VOTE_FESTA
type MsgMhfVoteFesta struct { type MsgMhfVoteFesta struct {
AckHandle uint32 AckHandle uint32
Unk uint32 FestaID uint32
GuildID uint32 GuildID uint32
TrialID uint32 TrialID uint32
} }
@@ -24,7 +24,7 @@ func (m *MsgMhfVoteFesta) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfVoteFesta) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfVoteFesta) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk = bf.ReadUint32() m.FestaID = bf.ReadUint32()
m.GuildID = bf.ReadUint32() m.GuildID = bf.ReadUint32()
m.TrialID = bf.ReadUint32() m.TrialID = bf.ReadUint32()
return nil return nil

View File

@@ -1,17 +1,16 @@
package mhfpacket 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"
) )
// MsgSysCastBinary represents the MSG_SYS_CAST_BINARY // MsgSysCastBinary represents the MSG_SYS_CAST_BINARY
type MsgSysCastBinary struct { type MsgSysCastBinary struct {
Unk0 uint16 Unk uint32
Unk1 uint16
BroadcastType uint8 BroadcastType uint8
MessageType uint8 MessageType uint8
RawDataPayload []byte RawDataPayload []byte
@@ -24,8 +23,7 @@ func (m *MsgSysCastBinary) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgSysCastBinary) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgSysCastBinary) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.Unk0 = bf.ReadUint16() m.Unk = bf.ReadUint32()
m.Unk1 = bf.ReadUint16()
m.BroadcastType = bf.ReadUint8() m.BroadcastType = bf.ReadUint8()
m.MessageType = bf.ReadUint8() m.MessageType = bf.ReadUint8()
dataSize := bf.ReadUint16() dataSize := bf.ReadUint16()

View File

@@ -2,7 +2,6 @@ package mhfpacket
import ( import (
"errors" "errors"
"erupe-ce/common/bfutil"
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
_config "erupe-ce/config" _config "erupe-ce/config"
"erupe-ce/network" "erupe-ce/network"
@@ -29,8 +28,8 @@ func (m *MsgSysCreateAcquireSemaphore) Parse(bf *byteframe.ByteFrame, ctx *clien
if _config.ErupeConfig.RealClientMode >= _config.S7 { // Assuming this was added with Ravi? if _config.ErupeConfig.RealClientMode >= _config.S7 { // Assuming this was added with Ravi?
m.PlayerCount = bf.ReadUint8() m.PlayerCount = bf.ReadUint8()
} }
SemaphoreIDLength := bf.ReadUint8() bf.ReadUint8() // SemaphoreID length
m.SemaphoreID = string(bfutil.UpToNull(bf.ReadBytes(uint(SemaphoreIDLength)))) m.SemaphoreID = string(bf.ReadNullTerminatedBytes())
return nil return nil
} }

View File

@@ -2,6 +2,7 @@ package mhfpacket
import ( import (
"errors" "errors"
_config "erupe-ce/config"
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
"erupe-ce/network" "erupe-ce/network"
@@ -10,10 +11,10 @@ import (
// MsgSysCreateSemaphore represents the MSG_SYS_CREATE_SEMAPHORE // MsgSysCreateSemaphore represents the MSG_SYS_CREATE_SEMAPHORE
type MsgSysCreateSemaphore struct { type MsgSysCreateSemaphore struct {
AckHandle uint32 AckHandle uint32
Unk0 uint16 Unk0 uint16
DataSize uint16 PlayerCount uint8
RawDataPayload []byte SemaphoreID string
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -25,8 +26,11 @@ func (m *MsgSysCreateSemaphore) Opcode() network.PacketID {
func (m *MsgSysCreateSemaphore) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgSysCreateSemaphore) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint16() m.Unk0 = bf.ReadUint16()
m.DataSize = bf.ReadUint16() if _config.ErupeConfig.RealClientMode >= _config.S7 { // Assuming this was added with Ravi?
m.RawDataPayload = bf.ReadBytes(uint(m.DataSize)) m.PlayerCount = bf.ReadUint8()
}
bf.ReadUint8() // SemaphoreID length
m.SemaphoreID = string(bf.ReadNullTerminatedBytes())
return nil return nil
} }

View File

@@ -4,7 +4,6 @@ import (
"errors" "errors"
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
"erupe-ce/common/bfutil"
"erupe-ce/network" "erupe-ce/network"
"erupe-ce/network/clientctx" "erupe-ce/network/clientctx"
) )
@@ -25,8 +24,8 @@ func (m *MsgSysEnterStage) Opcode() network.PacketID {
func (m *MsgSysEnterStage) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgSysEnterStage) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.UnkBool = bf.ReadUint8() m.UnkBool = bf.ReadUint8()
stageIDLength := bf.ReadUint8() bf.ReadUint8()
m.StageID = string(bfutil.UpToNull(bf.ReadBytes(uint(stageIDLength)))) m.StageID = string(bf.ReadNullTerminatedBytes())
return nil return nil
} }

View File

@@ -3,7 +3,6 @@ package mhfpacket
import ( import (
"errors" "errors"
"erupe-ce/common/bfutil"
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
"erupe-ce/network" "erupe-ce/network"
"erupe-ce/network/clientctx" "erupe-ce/network/clientctx"
@@ -27,8 +26,8 @@ func (m *MsgSysEnumerateClient) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Cl
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint8() m.Unk0 = bf.ReadUint8()
m.Get = bf.ReadUint8() m.Get = bf.ReadUint8()
stageIDLength := bf.ReadUint8() bf.ReadUint8() // StageID length
m.StageID = string(bfutil.UpToNull(bf.ReadBytes(uint(stageIDLength)))) m.StageID = string(bf.ReadNullTerminatedBytes())
return nil return nil
} }

View File

@@ -4,9 +4,9 @@ import (
"errors" "errors"
"erupe-ce/common/bfutil" "erupe-ce/common/bfutil"
"erupe-ce/common/byteframe"
"erupe-ce/network" "erupe-ce/network"
"erupe-ce/network/clientctx" "erupe-ce/network/clientctx"
"erupe-ce/common/byteframe"
) )
type scenarioFileIdentifer struct { type scenarioFileIdentifer struct {

View File

@@ -2,7 +2,6 @@ package mhfpacket
import ( import (
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
"erupe-ce/common/bfutil"
"erupe-ce/network" "erupe-ce/network"
"erupe-ce/network/clientctx" "erupe-ce/network/clientctx"
) )
@@ -27,8 +26,8 @@ func (m *MsgSysGetStageBinary) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Cli
m.BinaryType0 = bf.ReadUint8() m.BinaryType0 = bf.ReadUint8()
m.BinaryType1 = bf.ReadUint8() m.BinaryType1 = bf.ReadUint8()
m.Unk0 = bf.ReadUint32() m.Unk0 = bf.ReadUint32()
stageIDLength := bf.ReadUint8() bf.ReadUint8() // StageID length
m.StageID = string(bfutil.UpToNull(bf.ReadBytes(uint(stageIDLength)))) m.StageID = string(bf.ReadNullTerminatedBytes())
return nil return nil
} }

View File

@@ -1,18 +1,16 @@
package mhfpacket 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"
) )
// MsgSysHideClient represents the MSG_SYS_HIDE_CLIENT // MsgSysHideClient represents the MSG_SYS_HIDE_CLIENT
type MsgSysHideClient struct { type MsgSysHideClient struct {
Hide bool Hide bool
Unk0 uint16 // Hardcoded 0 in binary
Unk1 uint8 // Hardcoded 0 in binary
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -23,8 +21,9 @@ func (m *MsgSysHideClient) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgSysHideClient) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgSysHideClient) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.Hide = bf.ReadBool() m.Hide = bf.ReadBool()
m.Unk0 = bf.ReadUint16() bf.ReadUint8() // Zeroed
m.Unk1 = bf.ReadUint8() bf.ReadUint8() // Zeroed
bf.ReadUint8() // Zeroed
return nil return nil
} }

View File

@@ -1,18 +1,17 @@
package mhfpacket 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"
) )
// MsgSysIssueLogkey represents the MSG_SYS_ISSUE_LOGKEY // MsgSysIssueLogkey represents the MSG_SYS_ISSUE_LOGKEY
type MsgSysIssueLogkey struct { type MsgSysIssueLogkey struct {
AckHandle uint32 AckHandle uint32
Unk0 uint16 // Hardcoded 00 01 in binary Unk0 uint16
Unk1 uint16 // Hardcoded 0 in binary.
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -24,7 +23,7 @@ func (m *MsgSysIssueLogkey) Opcode() network.PacketID {
func (m *MsgSysIssueLogkey) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgSysIssueLogkey) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint16() m.Unk0 = bf.ReadUint16()
m.Unk1 = bf.ReadUint16() bf.ReadUint16() // Zeroed
return nil return nil
} }

View File

@@ -11,7 +11,7 @@ import (
type MsgSysLoadRegister struct { type MsgSysLoadRegister struct {
AckHandle uint32 AckHandle uint32
RegisterID uint32 RegisterID uint32
Unk1 uint8 Values uint8
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -23,9 +23,9 @@ func (m *MsgSysLoadRegister) Opcode() network.PacketID {
func (m *MsgSysLoadRegister) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgSysLoadRegister) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.RegisterID = bf.ReadUint32() m.RegisterID = bf.ReadUint32()
m.Unk1 = bf.ReadUint8() m.Values = bf.ReadUint8()
_ = bf.ReadUint8() bf.ReadUint8() // Zeroed
_ = bf.ReadUint16() bf.ReadUint16() // Zeroed
return nil return nil
} }

View File

@@ -1,24 +1,22 @@
package mhfpacket 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"
) )
// MsgSysLogin represents the MSG_SYS_LOGIN // MsgSysLogin represents the MSG_SYS_LOGIN
type MsgSysLogin struct { type MsgSysLogin struct {
AckHandle uint32 AckHandle uint32
CharID0 uint32 CharID0 uint32
LoginTokenNumber uint32 LoginTokenNumber uint32
HardcodedZero0 uint16 HardcodedZero0 uint16
RequestVersion uint16 RequestVersion uint16
CharID1 uint32 CharID1 uint32
HardcodedZero1 uint16 LoginTokenString string
LoginTokenStringLength uint16 // Hardcoded to 0x11
LoginTokenString string
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -34,8 +32,8 @@ func (m *MsgSysLogin) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContex
m.HardcodedZero0 = bf.ReadUint16() m.HardcodedZero0 = bf.ReadUint16()
m.RequestVersion = bf.ReadUint16() m.RequestVersion = bf.ReadUint16()
m.CharID1 = bf.ReadUint32() m.CharID1 = bf.ReadUint32()
m.HardcodedZero1 = bf.ReadUint16() bf.ReadUint16() // Zeroed
m.LoginTokenStringLength = bf.ReadUint16() bf.ReadUint16() // Always 11
m.LoginTokenString = string(bf.ReadNullTerminatedBytes()) m.LoginTokenString = string(bf.ReadNullTerminatedBytes())
return nil return nil
} }

View File

@@ -23,7 +23,7 @@ func (m *MsgSysOperateRegister) Opcode() network.PacketID {
func (m *MsgSysOperateRegister) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgSysOperateRegister) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.SemaphoreID = bf.ReadUint32() m.SemaphoreID = bf.ReadUint32()
_ = bf.ReadUint16() bf.ReadUint16() // Zeroed
dataSize := bf.ReadUint16() dataSize := bf.ReadUint16()
m.RawDataPayload = bf.ReadBytes(uint(dataSize)) m.RawDataPayload = bf.ReadBytes(uint(dataSize))
return nil return nil

View File

@@ -1,21 +1,19 @@
package mhfpacket 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"
) )
// MsgSysRecordLog represents the MSG_SYS_RECORD_LOG // MsgSysRecordLog represents the MSG_SYS_RECORD_LOG
type MsgSysRecordLog struct { type MsgSysRecordLog struct {
AckHandle uint32 AckHandle uint32
Unk0 uint32 Unk0 uint32
Unk1 uint16 // Hardcoded 0 Unk1 uint32
HardcodedDataSize uint16 // Hardcoded 0x4AC Data []byte
Unk3 uint32 // Some shared ID with MSG_MHF_GET_SEIBATTLE. World ID??
DataBuf []byte
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -27,10 +25,10 @@ func (m *MsgSysRecordLog) Opcode() network.PacketID {
func (m *MsgSysRecordLog) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgSysRecordLog) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint32() m.Unk0 = bf.ReadUint32()
m.Unk1 = bf.ReadUint16() bf.ReadUint16() // Zeroed
m.HardcodedDataSize = bf.ReadUint16() size := bf.ReadUint16()
m.Unk3 = bf.ReadUint32() m.Unk1 = bf.ReadUint32()
m.DataBuf = bf.ReadBytes(uint(m.HardcodedDataSize)) m.Data = bf.ReadBytes(uint(size))
return nil return nil
} }

View File

@@ -3,7 +3,6 @@ package mhfpacket
import ( import (
"errors" "errors"
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
"erupe-ce/common/bfutil"
"erupe-ce/network" "erupe-ce/network"
"erupe-ce/network/clientctx" "erupe-ce/network/clientctx"
) )
@@ -24,8 +23,8 @@ func (m *MsgSysReserveStage) Opcode() network.PacketID {
func (m *MsgSysReserveStage) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgSysReserveStage) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Ready = bf.ReadUint8() m.Ready = bf.ReadUint8()
stageIDLength := bf.ReadUint8() _ = bf.ReadUint8() // StageID length
m.StageID = string(bfutil.UpToNull(bf.ReadBytes(uint(stageIDLength)))) m.StageID = string(bf.ReadNullTerminatedBytes())
return nil return nil
} }

View File

@@ -1,17 +1,17 @@
package mhfpacket 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"
) )
// MsgSysRightsReload represents the MSG_SYS_RIGHTS_RELOAD // MsgSysRightsReload represents the MSG_SYS_RIGHTS_RELOAD
type MsgSysRightsReload struct{ type MsgSysRightsReload struct {
AckHandle uint32 AckHandle uint32
Unk0 byte Unk0 []byte
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -22,7 +22,7 @@ func (m *MsgSysRightsReload) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgSysRightsReload) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgSysRightsReload) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint8() m.Unk0 = bf.ReadBytes(uint(bf.ReadUint8()))
return nil return nil
} }

View File

@@ -2,7 +2,6 @@ package mhfpacket
import ( import (
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
"erupe-ce/common/bfutil"
"erupe-ce/network" "erupe-ce/network"
"erupe-ce/network/clientctx" "erupe-ce/network/clientctx"
) )
@@ -24,9 +23,9 @@ func (m *MsgSysSetStageBinary) Opcode() network.PacketID {
func (m *MsgSysSetStageBinary) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgSysSetStageBinary) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.BinaryType0 = bf.ReadUint8() m.BinaryType0 = bf.ReadUint8()
m.BinaryType1 = bf.ReadUint8() m.BinaryType1 = bf.ReadUint8()
stageIDLength := bf.ReadUint8() // <= 0x20 bf.ReadUint8() // StageID length <= 0x20
dataSize := bf.ReadUint16() // <= 0x400 dataSize := bf.ReadUint16() // <= 0x400
m.StageID = string(bfutil.UpToNull(bf.ReadBytes(uint(stageIDLength)))) m.StageID = string(bf.ReadNullTerminatedBytes())
m.RawDataPayload = bf.ReadBytes(uint(dataSize)) m.RawDataPayload = bf.ReadBytes(uint(dataSize))
return nil return nil
} }

View File

@@ -1,17 +1,16 @@
package mhfpacket 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"
) )
// MsgSysSetStagePass represents the MSG_SYS_SET_STAGE_PASS // MsgSysSetStagePass represents the MSG_SYS_SET_STAGE_PASS
type MsgSysSetStagePass struct { type MsgSysSetStagePass struct {
Unk0 uint8 // Hardcoded 0 in the binary Password string // NULL-terminated string
Password string // NULL-terminated string
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -21,8 +20,8 @@ func (m *MsgSysSetStagePass) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgSysSetStagePass) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgSysSetStagePass) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.Unk0 = bf.ReadUint8() bf.ReadUint8() // Zeroed
_ = bf.ReadUint8() // Password length bf.ReadUint8() // Password length
m.Password = string(bf.ReadNullTerminatedBytes()) m.Password = string(bf.ReadNullTerminatedBytes())
return nil return nil
} }

View File

@@ -23,11 +23,9 @@ type TerminalLogEntry struct {
// MsgSysTerminalLog represents the MSG_SYS_TERMINAL_LOG // MsgSysTerminalLog represents the MSG_SYS_TERMINAL_LOG
type MsgSysTerminalLog struct { type MsgSysTerminalLog struct {
AckHandle uint32 AckHandle uint32
LogID uint32 // 0 on the first packet, and the server sends back a value to use for subsequent requests. LogID uint32 // 0 on the first packet, and the server sends back a value to use for subsequent requests.
EntryCount uint16 Entries []TerminalLogEntry
Unk0 uint16 // Hardcoded 0 in the binary
Entries []*TerminalLogEntry
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -39,11 +37,11 @@ func (m *MsgSysTerminalLog) Opcode() network.PacketID {
func (m *MsgSysTerminalLog) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgSysTerminalLog) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.LogID = bf.ReadUint32() m.LogID = bf.ReadUint32()
m.EntryCount = bf.ReadUint16() entryCount := int(bf.ReadUint16())
m.Unk0 = bf.ReadUint16() bf.ReadUint16() // Zeroed
for i := 0; i < int(m.EntryCount); i++ { var e TerminalLogEntry
e := &TerminalLogEntry{} for i := 0; i < entryCount; i++ {
e.Index = bf.ReadUint32() e.Index = bf.ReadUint32()
e.Type1 = bf.ReadUint8() e.Type1 = bf.ReadUint8()
e.Type2 = bf.ReadUint8() e.Type2 = bf.ReadUint8()

View File

@@ -2,7 +2,6 @@ package mhfpacket
import ( import (
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
"erupe-ce/common/bfutil"
"erupe-ce/network" "erupe-ce/network"
"erupe-ce/network/clientctx" "erupe-ce/network/clientctx"
) )
@@ -27,8 +26,8 @@ func (m *MsgSysWaitStageBinary) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Cl
m.BinaryType0 = bf.ReadUint8() m.BinaryType0 = bf.ReadUint8()
m.BinaryType1 = bf.ReadUint8() m.BinaryType1 = bf.ReadUint8()
m.Unk0 = bf.ReadUint32() m.Unk0 = bf.ReadUint32()
stageIDLength := bf.ReadUint8() bf.ReadUint8() // StageID length
m.StageID = string(bfutil.UpToNull(bf.ReadBytes(uint(stageIDLength)))) m.StageID = string(bf.ReadNullTerminatedBytes())
return nil return nil
} }

View File

@@ -0,0 +1,11 @@
BEGIN;
ALTER TABLE gook RENAME TO goocoo;
ALTER TABLE goocoo RENAME COLUMN gook0 TO goocoo0;
ALTER TABLE goocoo RENAME COLUMN gook1 TO goocoo1;
ALTER TABLE goocoo RENAME COLUMN gook2 TO goocoo2;
ALTER TABLE goocoo RENAME COLUMN gook3 TO goocoo3;
ALTER TABLE goocoo RENAME COLUMN gook4 TO goocoo4;
END;

View File

@@ -0,0 +1,9 @@
BEGIN;
CREATE TABLE IF NOT EXISTS scenario_counter (
id serial primary key,
scenario_id numeric not null,
category_id numeric not null
);
END;

View File

@@ -0,0 +1,12 @@
CREATE TABLE public.kill_logs
(
id serial,
character_id integer NOT NULL,
monster integer NOT NULL,
quantity integer NOT NULL,
timestamp timestamp with time zone NOT NULL,
PRIMARY KEY (id)
);
ALTER TABLE IF EXISTS public.guild_characters
ADD COLUMN box_claimed timestamp with time zone DEFAULT now();

View File

@@ -0,0 +1,26 @@
BEGIN;
ALTER TABLE IF EXISTS public.guild_hunts DROP COLUMN IF EXISTS hunters;
ALTER TABLE IF EXISTS public.guild_characters
ADD COLUMN treasure_hunt integer;
ALTER TABLE IF EXISTS public.guild_hunts
ADD COLUMN start timestamp with time zone NOT NULL DEFAULT now();
UPDATE guild_hunts SET start=to_timestamp(return);
ALTER TABLE IF EXISTS public.guild_hunts DROP COLUMN IF EXISTS "return";
ALTER TABLE IF EXISTS public.guild_hunts
RENAME claimed TO collected;
CREATE TABLE public.guild_hunts_claimed
(
hunt_id integer NOT NULL,
character_id integer NOT NULL
);
ALTER TABLE IF EXISTS public.guild_hunts DROP COLUMN IF EXISTS treasure;
END;

View File

@@ -0,0 +1,36 @@
BEGIN;
-- This will delete all of your old distribution data!
--ALTER TABLE IF EXISTS public.distribution DROP COLUMN IF EXISTS data;
CREATE TABLE public.distribution_items
(
id serial PRIMARY KEY,
distribution_id integer NOT NULL,
item_type integer NOT NULL,
item_id integer,
quantity integer
);
ALTER TABLE IF EXISTS public.distribution ALTER COLUMN min_hr DROP DEFAULT;
ALTER TABLE IF EXISTS public.distribution ALTER COLUMN max_hr DROP DEFAULT;
ALTER TABLE IF EXISTS public.distribution ALTER COLUMN min_sr DROP DEFAULT;
ALTER TABLE IF EXISTS public.distribution ALTER COLUMN max_sr DROP DEFAULT;
ALTER TABLE IF EXISTS public.distribution ALTER COLUMN min_gr DROP DEFAULT;
ALTER TABLE IF EXISTS public.distribution ALTER COLUMN max_gr DROP DEFAULT;
ALTER TABLE IF EXISTS public.distribution ALTER COLUMN min_hr DROP NOT NULL;
ALTER TABLE IF EXISTS public.distribution ALTER COLUMN max_hr DROP NOT NULL;
ALTER TABLE IF EXISTS public.distribution ALTER COLUMN min_sr DROP NOT NULL;
ALTER TABLE IF EXISTS public.distribution ALTER COLUMN max_sr DROP NOT NULL;
ALTER TABLE IF EXISTS public.distribution ALTER COLUMN min_gr DROP NOT NULL;
ALTER TABLE IF EXISTS public.distribution ALTER COLUMN max_gr DROP NOT NULL;
UPDATE distribution SET min_hr=NULL WHERE min_hr=65535;
UPDATE distribution SET max_hr=NULL WHERE max_hr=65535;
UPDATE distribution SET min_sr=NULL WHERE min_sr=65535;
UPDATE distribution SET max_sr=NULL WHERE max_sr=65535;
UPDATE distribution SET min_gr=NULL WHERE min_gr=65535;
UPDATE distribution SET max_gr=NULL WHERE max_gr=65535;
END;

View File

@@ -0,0 +1,5 @@
BEGIN;
ALTER TABLE IF EXISTS public.event_quests ADD COLUMN IF NOT EXISTS flags integer;
END;

View File

@@ -0,0 +1,5 @@
BEGIN;
ALTER TABLE IF EXISTS public.guild_characters ADD COLUMN trial_vote integer;
END;

View File

@@ -4,6 +4,7 @@ import (
"encoding/binary" "encoding/binary"
"encoding/hex" "encoding/hex"
"erupe-ce/common/mhfcourse" "erupe-ce/common/mhfcourse"
"erupe-ce/common/mhfmon"
ps "erupe-ce/common/pascalstring" ps "erupe-ce/common/pascalstring"
"erupe-ce/common/stringsupport" "erupe-ce/common/stringsupport"
_config "erupe-ce/config" _config "erupe-ce/config"
@@ -16,8 +17,9 @@ import (
"crypto/rand" "crypto/rand"
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
"erupe-ce/network/mhfpacket" "erupe-ce/network/mhfpacket"
"go.uber.org/zap"
"math/bits" "math/bits"
"go.uber.org/zap"
) )
// Temporary function to just return no results for a MSG_MHF_ENUMERATE* packet // Temporary function to just return no results for a MSG_MHF_ENUMERATE* packet
@@ -231,7 +233,7 @@ func logoutPlayer(s *Session) {
s.server.db.Exec("UPDATE characters SET time_played = $1 WHERE id = $2", timePlayed, s.charID) s.server.db.Exec("UPDATE characters SET time_played = $1 WHERE id = $2", timePlayed, s.charID)
treasureHuntUnregister(s) s.server.db.Exec(`UPDATE guild_characters SET treasure_hunt=NULL WHERE character_id=$1`, s.charID)
if s.stage == nil { if s.stage == nil {
return return
@@ -304,9 +306,20 @@ func handleMsgSysIssueLogkey(s *Session, p mhfpacket.MHFPacket) {
func handleMsgSysRecordLog(s *Session, p mhfpacket.MHFPacket) { func handleMsgSysRecordLog(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgSysRecordLog) pkt := p.(*mhfpacket.MsgSysRecordLog)
if _config.ErupeConfig.RealClientMode == _config.ZZ {
bf := byteframe.NewByteFrameFromBytes(pkt.Data)
bf.Seek(32, 0)
var val uint8
for i := 0; i < 176; i++ {
val = bf.ReadUint8()
if val > 0 && mhfmon.Monsters[i].Large {
s.server.db.Exec(`INSERT INTO kill_logs (character_id, monster, quantity, timestamp) VALUES ($1, $2, $3, $4)`, s.charID, i, val, TimeAdjusted())
}
}
}
// remove a client returning to town from reserved slots to make sure the stage is hidden from board // remove a client returning to town from reserved slots to make sure the stage is hidden from board
delete(s.stage.reservedClientSlots, s.charID) delete(s.stage.reservedClientSlots, s.charID)
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
} }
func handleMsgSysEcho(s *Session, p mhfpacket.MHFPacket) {} func handleMsgSysEcho(s *Session, p mhfpacket.MHFPacket) {}
@@ -598,7 +611,7 @@ func handleMsgMhfServerCommand(s *Session, p mhfpacket.MHFPacket) {}
func handleMsgMhfAnnounce(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfAnnounce(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfAnnounce) pkt := p.(*mhfpacket.MsgMhfAnnounce)
s.server.BroadcastRaviente(pkt.IPAddress, pkt.Port, pkt.StageID, pkt.Type) s.server.BroadcastRaviente(pkt.IPAddress, pkt.Port, pkt.StageID, pkt.Data.ReadUint8())
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
} }
@@ -692,16 +705,16 @@ func handleMsgMhfUpdateUnionItem(s *Session, p mhfpacket.MHFPacket) {
// Update item stacks // Update item stacks
newItems := make([]Item, len(oldItems)) newItems := make([]Item, len(oldItems))
copy(newItems, oldItems) copy(newItems, oldItems)
for i := 0; i < int(pkt.Amount); i++ { for i := 0; i < len(pkt.Items); i++ {
for j := 0; j <= len(oldItems); j++ { for j := 0; j <= len(oldItems); j++ {
if j == len(oldItems) { if j == len(oldItems) {
var newItem Item var newItem Item
newItem.ItemId = pkt.Items[i].ItemId newItem.ItemId = pkt.Items[i].ItemID
newItem.Amount = pkt.Items[i].Amount newItem.Amount = pkt.Items[i].Amount
newItems = append(newItems, newItem) newItems = append(newItems, newItem)
break break
} }
if pkt.Items[i].ItemId == oldItems[j].ItemId { if pkt.Items[i].ItemID == oldItems[j].ItemId {
newItems[j].Amount = pkt.Items[i].Amount newItems[j].Amount = pkt.Items[i].Amount
break break
} }
@@ -789,20 +802,20 @@ func getGookData(s *Session, cid uint32) (uint16, []byte) {
var count uint16 var count uint16
bf := byteframe.NewByteFrame() bf := byteframe.NewByteFrame()
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
err := s.server.db.QueryRow(fmt.Sprintf("SELECT gook%d FROM gook WHERE id=$1", i), cid).Scan(&data) err := s.server.db.QueryRow(fmt.Sprintf("SELECT goocoo%d FROM goocoo WHERE id=$1", i), cid).Scan(&data)
if err != nil { if err != nil {
s.server.db.Exec("INSERT INTO gook (id) VALUES ($1)", s.charID) s.server.db.Exec("INSERT INTO goocoo (id) VALUES ($1)", s.charID)
return 0, bf.Data() return 0, bf.Data()
} }
if err == nil && data != nil { if err == nil && data != nil {
count++ count++
if s.charID == cid && count == 1 { if s.charID == cid && count == 1 {
gook := byteframe.NewByteFrameFromBytes(data) goocoo := byteframe.NewByteFrameFromBytes(data)
bf.WriteBytes(gook.ReadBytes(4)) bf.WriteBytes(goocoo.ReadBytes(4))
d := gook.ReadBytes(2) d := goocoo.ReadBytes(2)
bf.WriteBytes(d) bf.WriteBytes(d)
bf.WriteBytes(d) bf.WriteBytes(d)
bf.WriteBytes(gook.DataFromCurrent()) bf.WriteBytes(goocoo.DataFromCurrent())
} else { } else {
bf.WriteBytes(data) bf.WriteBytes(data)
} }
@@ -822,744 +835,75 @@ func handleMsgMhfEnumerateGuacot(s *Session, p mhfpacket.MHFPacket) {
func handleMsgMhfUpdateGuacot(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfUpdateGuacot(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfUpdateGuacot) pkt := p.(*mhfpacket.MsgMhfUpdateGuacot)
for _, gook := range pkt.Gooks { for _, goocoo := range pkt.Goocoos {
if !gook.Exists { if goocoo.Data1[0] == 0 {
s.server.db.Exec(fmt.Sprintf("UPDATE gook SET gook%d=NULL WHERE id=$1", gook.Index), s.charID) s.server.db.Exec(fmt.Sprintf("UPDATE goocoo SET goocoo%d=NULL WHERE id=$1", goocoo.Index), s.charID)
} else { } else {
bf := byteframe.NewByteFrame() bf := byteframe.NewByteFrame()
bf.WriteUint32(gook.Index) bf.WriteUint32(goocoo.Index)
bf.WriteUint16(gook.Type) for i := range goocoo.Data1 {
bf.WriteBytes(gook.Data) bf.WriteUint16(goocoo.Data1[i])
bf.WriteUint8(gook.NameLen) }
bf.WriteBytes(gook.Name) for i := range goocoo.Data2 {
s.server.db.Exec(fmt.Sprintf("UPDATE gook SET gook%d=$1 WHERE id=$2", gook.Index), bf.Data(), s.charID) bf.WriteUint32(goocoo.Data2[i])
dumpSaveData(s, bf.Data(), fmt.Sprintf("goocoo-%d", gook.Index)) }
bf.WriteUint8(uint8(len(goocoo.Name)))
bf.WriteBytes(goocoo.Name)
s.server.db.Exec(fmt.Sprintf("UPDATE goocoo SET goocoo%d=$1 WHERE id=$2", goocoo.Index), bf.Data(), s.charID)
dumpSaveData(s, bf.Data(), fmt.Sprintf("goocoo-%d", goocoo.Index))
} }
} }
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
}
type Scenario struct {
MainID uint32
// 0 = Basic
// 1 = Veteran
// 3 = Other
// 6 = Pallone
// 7 = Diva
CategoryID uint8
} }
func handleMsgMhfInfoScenarioCounter(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfInfoScenarioCounter(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfInfoScenarioCounter) pkt := p.(*mhfpacket.MsgMhfInfoScenarioCounter)
scenarioCounter := []struct { var scenarios []Scenario
MainID uint32 var scenario Scenario
Unk1 uint8 // Bool item exchange? scenarioData, err := s.server.db.Queryx("SELECT scenario_id, category_id FROM scenario_counter")
// 0 = basic, 1 = veteran, 3 = other, 6 = pallone, 7 = diva if err != nil {
CategoryID uint8 scenarioData.Close()
}{ s.logger.Error("Failed to get scenario counter info from db", zap.Error(err))
//000000110000 doAckBufSucceed(s, pkt.AckHandle, make([]byte, 1))
{ return
MainID: 0x00000011, Unk1: 0, CategoryID: 0, }
}, for scenarioData.Next() {
// 0000005D0001 err = scenarioData.Scan(&scenario.MainID, &scenario.CategoryID)
{ if err != nil {
MainID: 0x0000005D, Unk1: 0, CategoryID: 1, continue
}, }
// 0000005C0001 scenarios = append(scenarios, scenario)
{
MainID: 0x0000005C, Unk1: 0, CategoryID: 1,
},
// 000000510001
{
MainID: 0x00000051, Unk1: 0, CategoryID: 1,
},
// 0000005B0001
{
MainID: 0x0000005B, Unk1: 0, CategoryID: 1,
},
// 0000005A0001
{
MainID: 0x0000005A, Unk1: 0, CategoryID: 1,
},
// 000000590001
{
MainID: 0x00000059, Unk1: 0, CategoryID: 1,
},
// 000000580001
{
MainID: 0x00000058, Unk1: 0, CategoryID: 1,
},
// 000000570001
{
MainID: 0x00000057, Unk1: 0, CategoryID: 1,
},
// 000000560001
{
MainID: 0x00000056, Unk1: 0, CategoryID: 1,
},
// 000000550001
{
MainID: 0x00000055, Unk1: 0, CategoryID: 1,
},
// 000000540001
{
MainID: 0x00000054, Unk1: 0, CategoryID: 1,
},
// 000000530001
{
MainID: 0x00000053, Unk1: 0, CategoryID: 1,
},
// 000000520001
{
MainID: 0x00000052, Unk1: 0, CategoryID: 1,
},
// 000000570103
{
MainID: 0x00000057, Unk1: 1, CategoryID: 3,
},
// 000000580103
{
MainID: 0x00000058, Unk1: 1, CategoryID: 3,
},
// 000000590103
{
MainID: 0x00000059, Unk1: 1, CategoryID: 3,
},
// 0000005A0103
{
MainID: 0x0000005A, Unk1: 1, CategoryID: 3,
},
// 0000005B0103
{
MainID: 0x0000005B, Unk1: 1, CategoryID: 3,
},
// 0000005C0103
{
MainID: 0x0000005C, Unk1: 1, CategoryID: 3,
},
// 000000530103
{
MainID: 0x00000053, Unk1: 1, CategoryID: 3,
},
// 000000560103
{
MainID: 0x00000056, Unk1: 1, CategoryID: 3,
},
// 0000003C0103
{
MainID: 0x0000003C, Unk1: 1, CategoryID: 3,
},
// 0000003A0103
{
MainID: 0x0000003A, Unk1: 1, CategoryID: 3,
},
// 0000003B0103
{
MainID: 0x0000003B, Unk1: 1, CategoryID: 3,
},
// 0000001B0103
{
MainID: 0x0000001B, Unk1: 1, CategoryID: 3,
},
// 000000190103
{
MainID: 0x00000019, Unk1: 1, CategoryID: 3,
},
// 0000001A0103
{
MainID: 0x0000001A, Unk1: 1, CategoryID: 3,
},
// 000000170103
{
MainID: 0x00000017, Unk1: 1, CategoryID: 3,
},
// 000000020103
{
MainID: 0x00000002, Unk1: 1, CategoryID: 3,
},
// 000000030103
{
MainID: 0x00000003, Unk1: 1, CategoryID: 3,
},
// 000000040103
{
MainID: 0x00000004, Unk1: 1, CategoryID: 3,
},
// 0000001F0103
{
MainID: 0x0000001F, Unk1: 1, CategoryID: 3,
},
// 000000200103
{
MainID: 0x00000020, Unk1: 1, CategoryID: 3,
},
// 000000210103
{
MainID: 0x00000021, Unk1: 1, CategoryID: 3,
},
// 000000220103
{
MainID: 0x00000022, Unk1: 1, CategoryID: 3,
},
// 000000230103
{
MainID: 0x00000023, Unk1: 1, CategoryID: 3,
},
// 000000240103
{
MainID: 0x00000024, Unk1: 1, CategoryID: 3,
},
// 000000250103
{
MainID: 0x00000025, Unk1: 1, CategoryID: 3,
},
// 000000280103
{
MainID: 0x00000028, Unk1: 1, CategoryID: 3,
},
// 000000260103
{
MainID: 0x00000026, Unk1: 1, CategoryID: 3,
},
// 000000270103
{
MainID: 0x00000027, Unk1: 1, CategoryID: 3,
},
// 000000300103
{
MainID: 0x00000030, Unk1: 1, CategoryID: 3,
},
// 0000000C0103
{
MainID: 0x0000000C, Unk1: 1, CategoryID: 3,
},
// 0000000D0103
{
MainID: 0x0000000D, Unk1: 1, CategoryID: 3,
},
// 0000001E0103
{
MainID: 0x0000001E, Unk1: 1, CategoryID: 3,
},
// 0000001D0103
{
MainID: 0x0000001D, Unk1: 1, CategoryID: 3,
},
// 0000002E0003
{
MainID: 0x0000002E, Unk1: 0, CategoryID: 3,
},
// 000000000004
{
MainID: 0x00000000, Unk1: 0, CategoryID: 4,
},
// 000000010004
{
MainID: 0x00000001, Unk1: 0, CategoryID: 4,
},
// 000000020004
{
MainID: 0x00000002, Unk1: 0, CategoryID: 4,
},
// 000000030004
{
MainID: 0x00000003, Unk1: 0, CategoryID: 4,
},
// 000000040004
{
MainID: 0x00000004, Unk1: 0, CategoryID: 4,
},
// 000000050004
{
MainID: 0x00000005, Unk1: 0, CategoryID: 4,
},
// 000000060004
{
MainID: 0x00000006, Unk1: 0, CategoryID: 4,
},
// 000000070004
{
MainID: 0x00000007, Unk1: 0, CategoryID: 4,
},
// 000000080004
{
MainID: 0x00000008, Unk1: 0, CategoryID: 4,
},
// 000000090004
{
MainID: 0x00000009, Unk1: 0, CategoryID: 4,
},
// 0000000A0004
{
MainID: 0x0000000A, Unk1: 0, CategoryID: 4,
},
// 0000000B0004
{
MainID: 0x0000000B, Unk1: 0, CategoryID: 4,
},
// 0000000C0004
{
MainID: 0x0000000C, Unk1: 0, CategoryID: 4,
},
// 0000000D0004
{
MainID: 0x0000000D, Unk1: 0, CategoryID: 4,
},
// 0000000E0004
{
MainID: 0x0000000E, Unk1: 0, CategoryID: 4,
},
// 000000320005
{
MainID: 0x00000032, Unk1: 0, CategoryID: 5,
},
// 000000330005
{
MainID: 0x00000033, Unk1: 0, CategoryID: 5,
},
// 000000340005
{
MainID: 0x00000034, Unk1: 0, CategoryID: 5,
},
// 000000350005
{
MainID: 0x00000035, Unk1: 0, CategoryID: 5,
},
// 000000360005
{
MainID: 0x00000036, Unk1: 0, CategoryID: 5,
},
// 000000370005
{
MainID: 0x00000037, Unk1: 0, CategoryID: 5,
},
// 000000380005
{
MainID: 0x00000038, Unk1: 0, CategoryID: 5,
},
// 0000003A0005
{
MainID: 0x0000003A, Unk1: 0, CategoryID: 5,
},
// 0000003F0005
{
MainID: 0x0000003F, Unk1: 0, CategoryID: 5,
},
// 000000400005
{
MainID: 0x00000040, Unk1: 0, CategoryID: 5,
},
// 000000410005
{
MainID: 0x00000041, Unk1: 0, CategoryID: 5,
},
// 000000430005
{
MainID: 0x00000043, Unk1: 0, CategoryID: 5,
},
// 000000470005
{
MainID: 0x00000047, Unk1: 0, CategoryID: 5,
},
// 0000004B0005
{
MainID: 0x0000004B, Unk1: 0, CategoryID: 5,
},
// 0000003D0005
{
MainID: 0x0000003D, Unk1: 0, CategoryID: 5,
},
// 000000440005
{
MainID: 0x00000044, Unk1: 0, CategoryID: 5,
},
// 000000420005
{
MainID: 0x00000042, Unk1: 0, CategoryID: 5,
},
// 0000004C0005
{
MainID: 0x0000004C, Unk1: 0, CategoryID: 5,
},
// 000000460005
{
MainID: 0x00000046, Unk1: 0, CategoryID: 5,
},
// 0000004D0005
{
MainID: 0x0000004D, Unk1: 0, CategoryID: 5,
},
// 000000480005
{
MainID: 0x00000048, Unk1: 0, CategoryID: 5,
},
// 0000004A0005
{
MainID: 0x0000004A, Unk1: 0, CategoryID: 5,
},
// 000000490005
{
MainID: 0x00000049, Unk1: 0, CategoryID: 5,
},
// 0000004E0005
{
MainID: 0x0000004E, Unk1: 0, CategoryID: 5,
},
// 000000450005
{
MainID: 0x00000045, Unk1: 0, CategoryID: 5,
},
// 0000003E0005
{
MainID: 0x0000003E, Unk1: 0, CategoryID: 5,
},
// 0000004F0005
{
MainID: 0x0000004F, Unk1: 0, CategoryID: 5,
},
// 000000000106
{
MainID: 0x00000000, Unk1: 1, CategoryID: 6,
},
// 000000010106
{
MainID: 0x00000001, Unk1: 1, CategoryID: 6,
},
// 000000020106
{
MainID: 0x00000002, Unk1: 1, CategoryID: 6,
},
// 000000030106
{
MainID: 0x00000003, Unk1: 1, CategoryID: 6,
},
// 000000040106
{
MainID: 0x00000004, Unk1: 1, CategoryID: 6,
},
// 000000050106
{
MainID: 0x00000005, Unk1: 1, CategoryID: 6,
},
// 000000060106
{
MainID: 0x00000006, Unk1: 1, CategoryID: 6,
},
// 000000070106
{
MainID: 0x00000007, Unk1: 1, CategoryID: 6,
},
// 000000080106
{
MainID: 0x00000008, Unk1: 1, CategoryID: 6,
},
// 000000090106
{
MainID: 0x00000009, Unk1: 1, CategoryID: 6,
},
// 000000110106
{
MainID: 0x00000011, Unk1: 1, CategoryID: 6,
},
// 0000000A0106
{
MainID: 0x0000000A, Unk1: 1, CategoryID: 6,
},
// 0000000B0106
{
MainID: 0x0000000B, Unk1: 1, CategoryID: 6,
},
// 0000000C0106
{
MainID: 0x0000000C, Unk1: 1, CategoryID: 6,
},
// 0000000D0106
{
MainID: 0x0000000D, Unk1: 1, CategoryID: 6,
},
// 0000000E0106
{
MainID: 0x0000000E, Unk1: 1, CategoryID: 6,
},
// 0000000F0106
{
MainID: 0x0000000F, Unk1: 1, CategoryID: 6,
},
// 000000100106
{
MainID: 0x00000010, Unk1: 1, CategoryID: 6,
},
// 000000320107
{
MainID: 0x00000032, Unk1: 1, CategoryID: 7,
},
// 000000350107
{
MainID: 0x00000035, Unk1: 1, CategoryID: 7,
},
// 0000003E0107
{
MainID: 0x0000003E, Unk1: 1, CategoryID: 7,
},
// 000000340107
{
MainID: 0x00000034, Unk1: 1, CategoryID: 7,
},
// 000000380107
{
MainID: 0x00000038, Unk1: 1, CategoryID: 7,
},
// 000000330107
{
MainID: 0x00000033, Unk1: 1, CategoryID: 7,
},
// 000000310107
{
MainID: 0x00000031, Unk1: 1, CategoryID: 7,
},
// 000000360107
{
MainID: 0x00000036, Unk1: 1, CategoryID: 7,
},
// 000000390107
{
MainID: 0x00000039, Unk1: 1, CategoryID: 7,
},
// 000000370107
{
MainID: 0x00000037, Unk1: 1, CategoryID: 7,
},
// 0000003D0107
{
MainID: 0x0000003D, Unk1: 1, CategoryID: 7,
},
// 0000003A0107
{
MainID: 0x0000003A, Unk1: 1, CategoryID: 7,
},
// 0000003C0107
{
MainID: 0x0000003C, Unk1: 1, CategoryID: 7,
},
// 0000003B0107
{
MainID: 0x0000003B, Unk1: 1, CategoryID: 7,
},
// 0000002A0107
{
MainID: 0x0000002A, Unk1: 1, CategoryID: 7,
},
// 000000300107
{
MainID: 0x00000030, Unk1: 1, CategoryID: 7,
},
// 000000280107
{
MainID: 0x00000028, Unk1: 1, CategoryID: 7,
},
// 000000270107
{
MainID: 0x00000027, Unk1: 1, CategoryID: 7,
},
// 0000002B0107
{
MainID: 0x0000002B, Unk1: 1, CategoryID: 7,
},
// 0000002E0107
{
MainID: 0x0000002E, Unk1: 1, CategoryID: 7,
},
// 000000290107
{
MainID: 0x00000029, Unk1: 1, CategoryID: 7,
},
// 0000002C0107
{
MainID: 0x0000002C, Unk1: 1, CategoryID: 7,
},
// 0000002D0107
{
MainID: 0x0000002D, Unk1: 1, CategoryID: 7,
},
// 0000002F0107
{
MainID: 0x0000002F, Unk1: 1, CategoryID: 7,
},
// 000000250107
{
MainID: 0x00000025, Unk1: 1, CategoryID: 7,
},
// 000000220107
{
MainID: 0x00000022, Unk1: 1, CategoryID: 7,
},
// 000000210107
{
MainID: 0x00000021, Unk1: 1, CategoryID: 7,
},
// 000000200107
{
MainID: 0x00000020, Unk1: 1, CategoryID: 7,
},
// 0000001C0107
{
MainID: 0x0000001C, Unk1: 1, CategoryID: 7,
},
// 0000001A0107
{
MainID: 0x0000001A, Unk1: 1, CategoryID: 7,
},
// 000000240107
{
MainID: 0x00000024, Unk1: 1, CategoryID: 7,
},
// 000000260107
{
MainID: 0x00000026, Unk1: 1, CategoryID: 7,
},
// 000000230107
{
MainID: 0x00000023, Unk1: 1, CategoryID: 7,
},
// 0000001B0107
{
MainID: 0x0000001B, Unk1: 1, CategoryID: 7,
},
// 0000001E0107
{
MainID: 0x0000001E, Unk1: 1, CategoryID: 7,
},
// 0000001F0107
{
MainID: 0x0000001F, Unk1: 1, CategoryID: 7,
},
// 0000001D0107
{
MainID: 0x0000001D, Unk1: 1, CategoryID: 7,
},
// 000000180107
{
MainID: 0x00000018, Unk1: 1, CategoryID: 7,
},
// 000000170107
{
MainID: 0x00000017, Unk1: 1, CategoryID: 7,
},
// 000000160107
{
MainID: 0x00000016, Unk1: 1, CategoryID: 7,
},
// 000000150107
// Missing file
// {
// MainID: 0x00000015, Unk1: 1, CategoryID: 7,
// },
// 000000190107
{
MainID: 0x00000019, Unk1: 1, CategoryID: 7,
},
// 000000140107
// Missing file
// {
// MainID: 0x00000014, Unk1: 1, CategoryID: 7,
// },
// 000000070107
// Missing file
// {
// MainID: 0x00000007, Unk1: 1, CategoryID: 7,
// },
// 000000090107
// Missing file
// {
// MainID: 0x00000009, Unk1: 1, CategoryID: 7,
// },
// 0000000D0107
// Missing file
// {
// MainID: 0x0000000D, Unk1: 1, CategoryID: 7,
// },
// 000000100107
// Missing file
// {
// MainID: 0x00000010, Unk1: 1, CategoryID: 7,
// },
// 0000000C0107
// Missing file
// {
// MainID: 0x0000000C, Unk1: 1, CategoryID: 7,
// },
// 0000000E0107
// Missing file
// {
// MainID: 0x0000000E, Unk1: 1, CategoryID: 7,
// },
// 0000000F0107
// Missing file
// {
// MainID: 0x0000000F, Unk1: 1, CategoryID: 7,
// },
// 000000130107
// Missing file
// {
// MainID: 0x00000013, Unk1: 1, CategoryID: 7,
// },
// 0000000A0107
// Missing file
// {
// MainID: 0x0000000A, Unk1: 1, CategoryID: 7,
// },
// 000000080107
// Missing file
// {
// MainID: 0x00000008, Unk1: 1, CategoryID: 7,
// },
// 0000000B0107
// Missing file
// {
// MainID: 0x0000000B, Unk1: 1, CategoryID: 7,
// },
// 000000120107
// Missing file
// {
// MainID: 0x00000012, Unk1: 1, CategoryID: 7,
// },
// 000000110107
// Missing file
// {
// MainID: 0x00000011, Unk1: 1, CategoryID: 7,
// },
// 000000060107
// Missing file
// {
// MainID: 0x00000006, Unk1: 1, CategoryID: 7,
// },
// 000000050107
// Missing file
// {
// MainID: 0x00000005, Unk1: 1, CategoryID: 7,
// },
// 000000040107
// Missing file
// {
// MainID: 0x00000004, Unk1: 1, CategoryID: 7,
// },
// 000000030107
{
MainID: 0x00000003, Unk1: 1, CategoryID: 7,
},
// 000000020107
{
MainID: 0x00000002, Unk1: 1, CategoryID: 7,
},
// 000000010107
{
MainID: 0x00000001, Unk1: 1, CategoryID: 7,
},
// 000000000107
{
MainID: 0x00000000, Unk1: 1, CategoryID: 7,
},
} }
resp := byteframe.NewByteFrame() // Trim excess scenarios
resp.WriteUint8(uint8(len(scenarioCounter))) // Entry count if len(scenarios) > 128 {
for _, entry := range scenarioCounter { scenarios = scenarios[:128]
resp.WriteUint32(entry.MainID)
resp.WriteUint8(entry.Unk1)
resp.WriteUint8(entry.CategoryID)
} }
doAckBufSucceed(s, pkt.AckHandle, resp.Data()) bf := byteframe.NewByteFrame()
bf.WriteUint8(uint8(len(scenarios)))
for _, scenario := range scenarios {
bf.WriteUint32(scenario.MainID)
// If item exchange
switch scenario.CategoryID {
case 3, 6, 7:
bf.WriteBool(true)
default:
bf.WriteBool(false)
}
bf.WriteUint8(scenario.CategoryID)
}
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
} }
func handleMsgMhfGetEtcPoints(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfGetEtcPoints(s *Session, p mhfpacket.MHFPacket) {

View File

@@ -6,11 +6,13 @@ import (
"erupe-ce/common/mhfcourse" "erupe-ce/common/mhfcourse"
"erupe-ce/common/token" "erupe-ce/common/token"
"erupe-ce/config" "erupe-ce/config"
"erupe-ce/network"
"erupe-ce/network/binpacket" "erupe-ce/network/binpacket"
"erupe-ce/network/mhfpacket" "erupe-ce/network/mhfpacket"
"fmt" "fmt"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
"math" "math"
"strconv"
"strings" "strings"
"time" "time"
@@ -82,29 +84,28 @@ func sendServerChatMessage(s *Session, message string) {
} }
func parseChatCommand(s *Session, command string) { func parseChatCommand(s *Session, command string) {
if strings.HasPrefix(command, commands["PSN"].Prefix) { args := strings.Split(command[1:], " ")
switch args[0] {
case commands["PSN"].Prefix:
if commands["PSN"].Enabled { if commands["PSN"].Enabled {
var id string if len(args) > 1 {
n, err := fmt.Sscanf(command, fmt.Sprintf("%s %%s", commands["PSN"].Prefix), &id)
if err != nil || n != 1 {
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandPSNError"], commands["PSN"].Prefix))
} else {
var exists int var exists int
s.server.db.QueryRow(`SELECT count(*) FROM users WHERE psn_id = $1`, id).Scan(&exists) s.server.db.QueryRow(`SELECT count(*) FROM users WHERE psn_id = $1`, args[1]).Scan(&exists)
if exists == 0 { if exists == 0 {
_, err = s.server.db.Exec(`UPDATE users u SET psn_id=$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)`, id, s.charID) _, err := s.server.db.Exec(`UPDATE users u SET psn_id=$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)`, args[1], s.charID)
if err == nil { if err == nil {
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandPSNSuccess"], id)) sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandPSNSuccess"], args[1]))
} }
} else { } else {
sendServerChatMessage(s, s.server.dict["commandPSNExists"]) sendServerChatMessage(s, s.server.dict["commandPSNExists"])
} }
} else {
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandPSNError"], commands["PSN"].Prefix))
} }
} else {
sendDisabledCommandMessage(s, commands["PSN"])
} }
} case commands["Reload"].Prefix:
if strings.HasPrefix(command, commands["Reload"].Prefix) {
// Flush all objects and users and reload
if commands["Reload"].Enabled { if commands["Reload"].Enabled {
sendServerChatMessage(s, s.server.dict["commandReload"]) sendServerChatMessage(s, s.server.dict["commandReload"])
var temp mhfpacket.MHFPacket var temp mhfpacket.MHFPacket
@@ -125,7 +126,7 @@ func parseChatCommand(s *Session, command string) {
deleteNotif.WriteUint16(uint16(temp.Opcode())) deleteNotif.WriteUint16(uint16(temp.Opcode()))
temp.Build(deleteNotif, s.clientContext) temp.Build(deleteNotif, s.clientContext)
} }
deleteNotif.WriteUint16(0x0010) deleteNotif.WriteUint16(uint16(network.MSG_SYS_END))
s.QueueSend(deleteNotif.Data()) s.QueueSend(deleteNotif.Data())
time.Sleep(500 * time.Millisecond) time.Sleep(500 * time.Millisecond)
reloadNotif := byteframe.NewByteFrame() reloadNotif := byteframe.NewByteFrame()
@@ -160,69 +161,58 @@ func parseChatCommand(s *Session, command string) {
reloadNotif.WriteUint16(uint16(temp.Opcode())) reloadNotif.WriteUint16(uint16(temp.Opcode()))
temp.Build(reloadNotif, s.clientContext) temp.Build(reloadNotif, s.clientContext)
} }
reloadNotif.WriteUint16(0x0010) reloadNotif.WriteUint16(uint16(network.MSG_SYS_END))
s.QueueSend(reloadNotif.Data()) s.QueueSend(reloadNotif.Data())
} else { } else {
sendDisabledCommandMessage(s, commands["Reload"]) sendDisabledCommandMessage(s, commands["Reload"])
} }
} case commands["KeyQuest"].Prefix:
if strings.HasPrefix(command, commands["KeyQuest"].Prefix) {
if commands["KeyQuest"].Enabled { if commands["KeyQuest"].Enabled {
if strings.HasPrefix(command, fmt.Sprintf("%s get", commands["KeyQuest"].Prefix)) { if len(args) > 1 {
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandKqfGet"], s.kqf)) if args[1] == "get" {
} else if strings.HasPrefix(command, fmt.Sprintf("%s set", commands["KeyQuest"].Prefix)) { sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandKqfGet"], s.kqf))
var hexs string } else if args[1] == "set" {
n, numerr := fmt.Sscanf(command, fmt.Sprintf("%s set %%s", commands["KeyQuest"].Prefix), &hexs) if len(args) > 2 && len(args[2]) == 16 {
if numerr != nil || n != 1 || len(hexs) != 16 { hexd, _ := hex.DecodeString(args[2])
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandKqfSetError"], commands["KeyQuest"].Prefix)) s.kqf = hexd
} else { s.kqfOverride = true
hexd, _ := hex.DecodeString(hexs) sendServerChatMessage(s, s.server.dict["commandKqfSetSuccess"])
s.kqf = hexd } else {
s.kqfOverride = true sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandKqfSetError"], commands["KeyQuest"].Prefix))
sendServerChatMessage(s, s.server.dict["commandKqfSetSuccess"]) }
} }
} }
} else { } else {
sendDisabledCommandMessage(s, commands["KeyQuest"]) sendDisabledCommandMessage(s, commands["KeyQuest"])
} }
} case commands["Rights"].Prefix:
if strings.HasPrefix(command, commands["Rights"].Prefix) {
// Set account rights
if commands["Rights"].Enabled { if commands["Rights"].Enabled {
var v uint32 if len(args) > 1 {
n, err := fmt.Sscanf(command, fmt.Sprintf("%s %%d", commands["Rights"].Prefix), &v) v, _ := strconv.Atoi(args[1])
if err != nil || n != 1 { _, err := s.server.db.Exec("UPDATE users u SET rights=$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", v, s.charID)
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandRightsError"], commands["Rights"].Prefix))
} else {
_, err = s.server.db.Exec("UPDATE users u SET rights=$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", v, s.charID)
if err == nil { if err == nil {
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandRightsSuccess"], v)) sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandRightsSuccess"], v))
} else {
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandRightsError"], commands["Rights"].Prefix))
} }
} else {
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandRightsError"], commands["Rights"].Prefix))
} }
} else { } else {
sendDisabledCommandMessage(s, commands["Rights"]) sendDisabledCommandMessage(s, commands["Rights"])
} }
} case commands["Course"].Prefix:
if strings.HasPrefix(command, commands["Course"].Prefix) {
if commands["Course"].Enabled { if commands["Course"].Enabled {
var name string if len(args) > 1 {
n, err := fmt.Sscanf(command, fmt.Sprintf("%s %%s", commands["Course"].Prefix), &name)
if err != nil || n != 1 {
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandCourseError"], commands["Course"].Prefix))
} else {
name = strings.ToLower(name)
for _, course := range mhfcourse.Courses() { for _, course := range mhfcourse.Courses() {
for _, alias := range course.Aliases() { for _, alias := range course.Aliases() {
if strings.ToLower(name) == strings.ToLower(alias) { if strings.ToLower(args[1]) == strings.ToLower(alias) {
if slices.Contains(s.server.erupeConfig.Courses, _config.Course{Name: course.Aliases()[0], Enabled: true}) { if slices.Contains(s.server.erupeConfig.Courses, _config.Course{Name: course.Aliases()[0], Enabled: true}) {
var delta, rightsInt uint32 var delta, rightsInt uint32
if mhfcourse.CourseExists(course.ID, s.courses) { if mhfcourse.CourseExists(course.ID, s.courses) {
ei := slices.IndexFunc(s.courses, func(c mhfcourse.Course) bool { ei := slices.IndexFunc(s.courses, func(c mhfcourse.Course) bool {
for _, alias := range c.Aliases() { for _, alias := range c.Aliases() {
if strings.ToLower(name) == strings.ToLower(alias) { if strings.ToLower(args[1]) == strings.ToLower(alias) {
return true return true
} }
} }
@@ -236,7 +226,7 @@ func parseChatCommand(s *Session, command string) {
delta = uint32(math.Pow(2, float64(course.ID))) delta = uint32(math.Pow(2, float64(course.ID)))
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandCourseEnabled"], course.Aliases()[0])) sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandCourseEnabled"], course.Aliases()[0]))
} }
err = 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) err := 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)
if err == nil { if err == nil {
s.server.db.Exec("UPDATE users u SET rights=$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", rightsInt+delta, s.charID) s.server.db.Exec("UPDATE users u SET rights=$1 WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$2)", rightsInt+delta, s.charID)
} }
@@ -248,82 +238,82 @@ func parseChatCommand(s *Session, command string) {
} }
} }
} }
} else {
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandCourseError"], commands["Course"].Prefix)) sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandCourseError"], commands["Course"].Prefix))
} }
} else { } else {
sendDisabledCommandMessage(s, commands["Course"]) sendDisabledCommandMessage(s, commands["Course"])
} }
} case commands["Raviente"].Prefix:
if strings.HasPrefix(command, commands["Raviente"].Prefix) {
if commands["Raviente"].Enabled { if commands["Raviente"].Enabled {
if getRaviSemaphore(s.server) != nil { if len(args) > 1 {
s.server.raviente.Lock() if s.server.getRaviSemaphore() != nil {
if !strings.HasPrefix(command, "!ravi ") { switch args[1] {
sendServerChatMessage(s, s.server.dict["commandRaviNoCommand"]) case "start":
} else { if s.server.raviente.register[1] == 0 {
if strings.HasPrefix(command, "!ravi start") { s.server.raviente.register[1] = s.server.raviente.register[3]
if s.server.raviente.register.startTime == 0 {
s.server.raviente.register.startTime = s.server.raviente.register.postTime
sendServerChatMessage(s, s.server.dict["commandRaviStartSuccess"]) sendServerChatMessage(s, s.server.dict["commandRaviStartSuccess"])
s.notifyRavi() s.notifyRavi()
} else { } else {
sendServerChatMessage(s, s.server.dict["commandRaviStartError"]) sendServerChatMessage(s, s.server.dict["commandRaviStartError"])
} }
} else if strings.HasPrefix(command, "!ravi cm") || strings.HasPrefix(command, "!ravi checkmultiplier") { case "cm", "check", "checkmultiplier", "multiplier":
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandRaviMultiplier"], s.server.raviente.GetRaviMultiplier(s.server))) sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandRaviMultiplier"], s.server.GetRaviMultiplier()))
} else if strings.HasPrefix(command, "!ravi sr") || strings.HasPrefix(command, "!ravi sendres") { case "sr", "sendres", "resurrection", "ss", "sendsed", "rs", "reqsed":
if s.server.raviente.state.stateData[28] > 0 { if s.server.erupeConfig.RealClientMode == _config.ZZ {
sendServerChatMessage(s, s.server.dict["commandRaviResSuccess"]) switch args[1] {
s.server.raviente.state.stateData[28] = 0 case "sr", "sendres", "resurrection":
if s.server.raviente.state[28] > 0 {
sendServerChatMessage(s, s.server.dict["commandRaviResSuccess"])
s.server.raviente.state[28] = 0
} else {
sendServerChatMessage(s, s.server.dict["commandRaviResError"])
}
case "ss", "sendsed":
sendServerChatMessage(s, s.server.dict["commandRaviSedSuccess"])
// Total BerRavi HP
HP := s.server.raviente.state[0] + s.server.raviente.state[1] + s.server.raviente.state[2] + s.server.raviente.state[3] + s.server.raviente.state[4]
s.server.raviente.support[1] = HP
case "rs", "reqsed":
sendServerChatMessage(s, s.server.dict["commandRaviRequest"])
// Total BerRavi HP
HP := s.server.raviente.state[0] + s.server.raviente.state[1] + s.server.raviente.state[2] + s.server.raviente.state[3] + s.server.raviente.state[4]
s.server.raviente.support[1] = HP + 1
}
} else { } else {
sendServerChatMessage(s, s.server.dict["commandRaviResError"]) sendServerChatMessage(s, s.server.dict["commandRaviVersion"])
} }
} else if strings.HasPrefix(command, "!ravi ss") || strings.HasPrefix(command, "!ravi sendsed") { default:
sendServerChatMessage(s, s.server.dict["commandRaviSedSuccess"])
// Total BerRavi HP
HP := s.server.raviente.state.stateData[0] + s.server.raviente.state.stateData[1] + s.server.raviente.state.stateData[2] + s.server.raviente.state.stateData[3] + s.server.raviente.state.stateData[4]
s.server.raviente.support.supportData[1] = HP
} else if strings.HasPrefix(command, "!ravi rs") || strings.HasPrefix(command, "!ravi reqsed") {
sendServerChatMessage(s, s.server.dict["commandRaviRequest"])
// Total BerRavi HP
HP := s.server.raviente.state.stateData[0] + s.server.raviente.state.stateData[1] + s.server.raviente.state.stateData[2] + s.server.raviente.state.stateData[3] + s.server.raviente.state.stateData[4]
s.server.raviente.support.supportData[1] = HP + 12
} else {
sendServerChatMessage(s, s.server.dict["commandRaviError"]) sendServerChatMessage(s, s.server.dict["commandRaviError"])
} }
} else {
sendServerChatMessage(s, s.server.dict["commandRaviNoPlayers"])
} }
s.server.raviente.Unlock()
} else { } else {
sendServerChatMessage(s, s.server.dict["commandRaviNoPlayers"]) sendServerChatMessage(s, s.server.dict["commandRaviError"])
} }
} else { } else {
sendDisabledCommandMessage(s, commands["Raviente"]) sendDisabledCommandMessage(s, commands["Raviente"])
} }
} case commands["Teleport"].Prefix:
if strings.HasPrefix(command, commands["Teleport"].Prefix) {
if commands["Teleport"].Enabled { if commands["Teleport"].Enabled {
var x, y int16 if len(args) > 2 {
n, err := fmt.Sscanf(command, fmt.Sprintf("%s %%d %%d", commands["Teleport"].Prefix), &x, &y) x, _ := strconv.ParseInt(args[1], 10, 16)
if err != nil || n != 2 { y, _ := strconv.ParseInt(args[2], 10, 16)
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandTeleportError"], commands["Teleport"].Prefix))
} else {
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandTeleportSuccess"], x, y))
// Make the inside of the casted binary
payload := byteframe.NewByteFrame() payload := byteframe.NewByteFrame()
payload.SetLE() payload.SetLE()
payload.WriteUint8(2) // SetState type(position == 2) payload.WriteUint8(2) // SetState type(position == 2)
payload.WriteInt16(x) // X payload.WriteInt16(int16(x)) // X
payload.WriteInt16(y) // Y payload.WriteInt16(int16(y)) // Y
payloadBytes := payload.Data() payloadBytes := payload.Data()
s.QueueSendMHF(&mhfpacket.MsgSysCastedBinary{ s.QueueSendMHF(&mhfpacket.MsgSysCastedBinary{
CharID: s.charID, CharID: s.charID,
MessageType: BinaryMessageTypeState, MessageType: BinaryMessageTypeState,
RawDataPayload: payloadBytes, RawDataPayload: payloadBytes,
}) })
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandTeleportSuccess"], x, y))
} else {
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandTeleportError"], commands["Teleport"].Prefix))
} }
} else { } else {
sendDisabledCommandMessage(s, commands["Teleport"]) sendDisabledCommandMessage(s, commands["Teleport"])
@@ -431,8 +421,9 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) {
} }
case BroadcastTypeServer: case BroadcastTypeServer:
if pkt.MessageType == 1 { if pkt.MessageType == 1 {
if getRaviSemaphore(s.server) != nil { raviSema := s.server.getRaviSemaphore()
s.server.BroadcastMHF(resp, s) if raviSema != nil {
raviSema.BroadcastMHF(resp, s)
} }
} else { } else {
s.server.BroadcastMHF(resp, s) s.server.BroadcastMHF(resp, s)

View File

@@ -19,7 +19,7 @@ const (
pRP // +2 pRP // +2
pHouseTier // +5 pHouseTier // +5
pHouseData // +195 pHouseData // +195
pBookshelfData // +5576 pBookshelfData // +lBookshelfData
pGalleryData // +1748 pGalleryData // +1748
pToreData // +240 pToreData // +240
pGardenData // +68 pGardenData // +68
@@ -28,6 +28,7 @@ const (
pHRP // +2 pHRP // +2
pGRP // +4 pGRP // +4
pKQF // +8 pKQF // +8
lBookshelfData
) )
type CharacterSaveData struct { type CharacterSaveData struct {
@@ -55,7 +56,7 @@ type CharacterSaveData struct {
} }
func getPointers() map[SavePointer]int { func getPointers() map[SavePointer]int {
pointers := map[SavePointer]int{pGender: 81} pointers := map[SavePointer]int{pGender: 81, lBookshelfData: 5576}
switch _config.ErupeConfig.RealClientMode { switch _config.ErupeConfig.RealClientMode {
case _config.ZZ: case _config.ZZ:
pointers[pWeaponID] = 128522 pointers[pWeaponID] = 128522
@@ -83,6 +84,22 @@ func getPointers() map[SavePointer]int {
pointers[pGardenData] = 106424 pointers[pGardenData] = 106424
pointers[pRP] = 106614 pointers[pRP] = 106614
pointers[pKQF] = 110720 pointers[pKQF] = 110720
case _config.F5, _config.F4:
pointers[pWeaponID] = 60522
pointers[pWeaponType] = 60789
pointers[pHouseTier] = 61900
pointers[pToreData] = 62228
pointers[pHRP] = 62550
pointers[pHouseData] = 62561
pointers[pBookshelfData] = 57118 // This pointer only half works
pointers[pGalleryData] = 72064
pointers[pGardenData] = 74424
pointers[pRP] = 74614
}
if _config.ErupeConfig.RealClientMode == _config.G5 {
pointers[lBookshelfData] = 5548
} else if _config.ErupeConfig.RealClientMode <= _config.GG {
pointers[lBookshelfData] = 4520
} }
return pointers return pointers
} }
@@ -179,6 +196,8 @@ func (save *CharacterSaveData) updateSaveDataWithStruct() {
if _config.ErupeConfig.RealClientMode >= _config.G10 { if _config.ErupeConfig.RealClientMode >= _config.G10 {
copy(save.decompSave[save.Pointers[pRP]:save.Pointers[pRP]+2], rpBytes) copy(save.decompSave[save.Pointers[pRP]:save.Pointers[pRP]+2], rpBytes)
copy(save.decompSave[save.Pointers[pKQF]:save.Pointers[pKQF]+8], save.KQF) copy(save.decompSave[save.Pointers[pKQF]:save.Pointers[pKQF]+8], save.KQF)
} else if _config.ErupeConfig.RealClientMode == _config.F5 || _config.ErupeConfig.RealClientMode == _config.F4 {
copy(save.decompSave[save.Pointers[pRP]:save.Pointers[pRP]+2], rpBytes)
} }
} }
@@ -191,21 +210,24 @@ func (save *CharacterSaveData) updateStructWithSaveData() {
save.Gender = false save.Gender = false
} }
if !save.IsNewCharacter { if !save.IsNewCharacter {
if _config.ErupeConfig.RealClientMode >= _config.G10 { if (_config.ErupeConfig.RealClientMode >= _config.F4 && _config.ErupeConfig.RealClientMode <= _config.F5) || _config.ErupeConfig.RealClientMode >= _config.G10 {
save.RP = binary.LittleEndian.Uint16(save.decompSave[save.Pointers[pRP] : save.Pointers[pRP]+2]) save.RP = binary.LittleEndian.Uint16(save.decompSave[save.Pointers[pRP] : save.Pointers[pRP]+2])
save.HouseTier = save.decompSave[save.Pointers[pHouseTier] : save.Pointers[pHouseTier]+5] save.HouseTier = save.decompSave[save.Pointers[pHouseTier] : save.Pointers[pHouseTier]+5]
save.HouseData = save.decompSave[save.Pointers[pHouseData] : save.Pointers[pHouseData]+195] save.HouseData = save.decompSave[save.Pointers[pHouseData] : save.Pointers[pHouseData]+195]
save.BookshelfData = save.decompSave[save.Pointers[pBookshelfData] : save.Pointers[pBookshelfData]+5576] save.BookshelfData = save.decompSave[save.Pointers[pBookshelfData] : save.Pointers[pBookshelfData]+save.Pointers[lBookshelfData]]
save.GalleryData = save.decompSave[save.Pointers[pGalleryData] : save.Pointers[pGalleryData]+1748] save.GalleryData = save.decompSave[save.Pointers[pGalleryData] : save.Pointers[pGalleryData]+1748]
save.ToreData = save.decompSave[save.Pointers[pToreData] : save.Pointers[pToreData]+240] save.ToreData = save.decompSave[save.Pointers[pToreData] : save.Pointers[pToreData]+240]
save.GardenData = save.decompSave[save.Pointers[pGardenData] : save.Pointers[pGardenData]+68] save.GardenData = save.decompSave[save.Pointers[pGardenData] : save.Pointers[pGardenData]+68]
save.WeaponType = save.decompSave[save.Pointers[pWeaponType]] save.WeaponType = save.decompSave[save.Pointers[pWeaponType]]
save.WeaponID = binary.LittleEndian.Uint16(save.decompSave[save.Pointers[pWeaponID] : save.Pointers[pWeaponID]+2]) save.WeaponID = binary.LittleEndian.Uint16(save.decompSave[save.Pointers[pWeaponID] : save.Pointers[pWeaponID]+2])
save.HRP = binary.LittleEndian.Uint16(save.decompSave[save.Pointers[pHRP] : save.Pointers[pHRP]+2]) save.HRP = binary.LittleEndian.Uint16(save.decompSave[save.Pointers[pHRP] : save.Pointers[pHRP]+2])
if save.HRP == uint16(999) { }
save.GR = grpToGR(binary.LittleEndian.Uint32(save.decompSave[save.Pointers[pGRP] : save.Pointers[pGRP]+4]))
} if _config.ErupeConfig.RealClientMode >= _config.G10 {
save.KQF = save.decompSave[save.Pointers[pKQF] : save.Pointers[pKQF]+8] save.KQF = save.decompSave[save.Pointers[pKQF] : save.Pointers[pKQF]+8]
if save.HRP == uint16(999) {
save.GR = grpToGR(int(binary.LittleEndian.Uint32(save.decompSave[save.Pointers[pGRP] : save.Pointers[pGRP]+4])))
}
} }
} }
return return

View File

@@ -60,20 +60,19 @@ func handleMsgMhfListMember(s *Session, p mhfpacket.MHFPacket) {
resp := byteframe.NewByteFrame() resp := byteframe.NewByteFrame()
resp.WriteUint32(0) // Blacklist count resp.WriteUint32(0) // Blacklist count
err := s.server.db.QueryRow("SELECT blocked FROM characters WHERE id=$1", s.charID).Scan(&csv) err := s.server.db.QueryRow("SELECT blocked FROM characters WHERE id=$1", s.charID).Scan(&csv)
if err != nil { if err == nil {
panic(err) cids := stringsupport.CSVElems(csv)
} for _, cid := range cids {
cids := stringsupport.CSVElems(csv) var name string
for _, cid := range cids { err = s.server.db.QueryRow("SELECT name FROM characters WHERE id=$1", cid).Scan(&name)
var name string if err != nil {
err = s.server.db.QueryRow("SELECT name FROM characters WHERE id=$1", cid).Scan(&name) continue
if err != nil { }
continue count++
resp.WriteUint32(uint32(cid))
resp.WriteUint32(16)
resp.WriteBytes(stringsupport.PaddedString(name, 16, true))
} }
count++
resp.WriteUint32(uint32(cid))
resp.WriteUint32(16)
resp.WriteBytes(stringsupport.PaddedString(name, 16, true))
} }
resp.Seek(0, 0) resp.Seek(0, 0)
resp.WriteUint32(count) resp.WriteUint32(count)
@@ -83,28 +82,28 @@ func handleMsgMhfListMember(s *Session, p mhfpacket.MHFPacket) {
func handleMsgMhfOprMember(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfOprMember(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfOprMember) pkt := p.(*mhfpacket.MsgMhfOprMember)
var csv string var csv string
if pkt.Blacklist { for _, cid := range pkt.CharIDs {
err := s.server.db.QueryRow("SELECT blocked FROM characters WHERE id=$1", s.charID).Scan(&csv) if pkt.Blacklist {
if err != nil { err := s.server.db.QueryRow("SELECT blocked FROM characters WHERE id=$1", s.charID).Scan(&csv)
panic(err) if err == nil {
if pkt.Operation {
csv = stringsupport.CSVRemove(csv, int(cid))
} else {
csv = stringsupport.CSVAdd(csv, int(cid))
}
s.server.db.Exec("UPDATE characters SET blocked=$1 WHERE id=$2", csv, s.charID)
}
} else { // Friendlist
err := s.server.db.QueryRow("SELECT friends FROM characters WHERE id=$1", s.charID).Scan(&csv)
if err == nil {
if pkt.Operation {
csv = stringsupport.CSVRemove(csv, int(cid))
} else {
csv = stringsupport.CSVAdd(csv, int(cid))
}
s.server.db.Exec("UPDATE characters SET friends=$1 WHERE id=$2", csv, s.charID)
}
} }
if pkt.Operation {
csv = stringsupport.CSVRemove(csv, int(pkt.CharID))
} else {
csv = stringsupport.CSVAdd(csv, int(pkt.CharID))
}
s.server.db.Exec("UPDATE characters SET blocked=$1 WHERE id=$2", csv, s.charID)
} else { // Friendlist
err := s.server.db.QueryRow("SELECT friends FROM characters WHERE id=$1", s.charID).Scan(&csv)
if err != nil {
panic(err)
}
if pkt.Operation {
csv = stringsupport.CSVRemove(csv, int(pkt.CharID))
} else {
csv = stringsupport.CSVAdd(csv, int(pkt.CharID))
}
s.server.db.Exec("UPDATE characters SET friends=$1 WHERE id=$2", csv, s.charID)
} }
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
} }

View File

@@ -2,6 +2,7 @@ package channelserver
import ( import (
"erupe-ce/common/stringsupport" "erupe-ce/common/stringsupport"
_config "erupe-ce/config"
"fmt" "fmt"
"io" "io"
"os" "os"
@@ -54,7 +55,7 @@ func handleMsgMhfSavedata(s *Session, p mhfpacket.MHFPacket) {
s.Name = characterSaveData.Name s.Name = characterSaveData.Name
} }
if characterSaveData.Name == s.Name { if characterSaveData.Name == s.Name || _config.ErupeConfig.RealClientMode <= _config.S10 {
characterSaveData.Save(s) characterSaveData.Save(s)
s.logger.Info("Wrote recompressed savedata back to DB.") s.logger.Info("Wrote recompressed savedata back to DB.")
} else { } else {
@@ -72,162 +73,39 @@ func handleMsgMhfSavedata(s *Session, p mhfpacket.MHFPacket) {
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
} }
func grpToGR(n uint32) uint16 { func grpToGR(n int) uint16 {
var gr uint16 var gr int
gr = 1 a := []int{208750, 593400, 993400, 1400900, 2315900, 3340900, 4505900, 5850900, 7415900, 9230900, 11345900, 100000000}
switch grp := int(n); { b := []int{7850, 8000, 8150, 9150, 10250, 11650, 13450, 15650, 18150, 21150, 23950}
case grp < 208750: // Up to 50 c := []int{51, 100, 150, 200, 300, 400, 500, 600, 700, 800, 900}
i := 0
for { for i := 0; i < len(a); i++ {
grp -= 500 if n < a[i] {
if grp <= 500 { if i == 0 {
if grp < 0 { for {
i-- n -= 500
if n <= 500 {
if n < 0 {
i--
}
break
} else {
i++
for j := 0; j < i; j++ {
n -= 150
}
}
} }
break gr = i + 2
} else { } else {
i++ n -= a[i-1]
for j := 0; j < i; j++ { gr = c[i-1]
grp -= 150 gr += n / b[i-1]
}
} }
break
} }
gr = uint16(i + 2)
break
case grp < 593400: // 51-99
grp -= 208750
i := 51
for {
if grp < 7850 {
break
}
i++
grp -= 7850
}
gr = uint16(i)
break
case grp < 993400: // 100-149
grp -= 593400
i := 100
for {
if grp < 8000 {
break
}
i++
grp -= 8000
}
gr = uint16(i)
break
case grp < 1400900: // 150-199
grp -= 993400
i := 150
for {
if grp < 8150 {
break
}
i++
grp -= 8150
}
gr = uint16(i)
break
case grp < 2315900: // 200-299
grp -= 1400900
i := 200
for {
if grp < 9150 {
break
}
i++
grp -= 9150
}
gr = uint16(i)
break
case grp < 3340900: // 300-399
grp -= 2315900
i := 300
for {
if grp < 10250 {
break
}
i++
grp -= 10250
}
gr = uint16(i)
break
case grp < 4505900: // 400-499
grp -= 3340900
i := 400
for {
if grp < 11650 {
break
}
i++
grp -= 11650
}
gr = uint16(i)
break
case grp < 5850900: // 500-599
grp -= 4505900
i := 500
for {
if grp < 13450 {
break
}
i++
grp -= 13450
}
gr = uint16(i)
break
case grp < 7415900: // 600-699
grp -= 5850900
i := 600
for {
if grp < 15650 {
break
}
i++
grp -= 15650
}
gr = uint16(i)
break
case grp < 9230900: // 700-799
grp -= 7415900
i := 700
for {
if grp < 18150 {
break
}
i++
grp -= 18150
}
gr = uint16(i)
break
case grp < 11345900: // 800-899
grp -= 9230900
i := 800
for {
if grp < 21150 {
break
}
i++
grp -= 21150
}
gr = uint16(i)
break
default: // 900+
grp -= 11345900
i := 900
for {
if grp < 23950 {
break
}
i++
grp -= 23950
}
gr = uint16(i)
break
} }
return gr return uint16(gr)
} }
func dumpSaveData(s *Session, data []byte, suffix string) { func dumpSaveData(s *Session, data []byte, suffix string) {
@@ -301,7 +179,7 @@ func handleMsgMhfLoadScenarioData(s *Session, p mhfpacket.MHFPacket) {
var scenarioData []byte var scenarioData []byte
bf := byteframe.NewByteFrame() bf := byteframe.NewByteFrame()
err := s.server.db.QueryRow("SELECT scenariodata FROM characters WHERE id = $1", 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 || len(scenarioData) < 10 {
s.logger.Error("Failed to load scenariodata", zap.Error(err)) s.logger.Error("Failed to load scenariodata", zap.Error(err))
bf.WriteBytes(make([]byte, 10)) bf.WriteBytes(make([]byte, 10))
} else { } else {

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