mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-05-07 14:54:56 +02:00
Reupload
This commit is contained in:
13
Erupe/.gitignore
vendored
Normal file
13
Erupe/.gitignore
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
www/jp/
|
||||
|
||||
.idea/
|
||||
vendor/
|
||||
bin/*.bin
|
||||
bin/quests/*.bin
|
||||
bin/questlists/*.bin
|
||||
bin/scenarios/*.bin
|
||||
bin/debug/*.bin
|
||||
savedata/
|
||||
Erupe.exe
|
||||
*.lnk
|
||||
*.bat
|
||||
1
Erupe/Event List.txt
Normal file
1
Erupe/Event List.txt
Normal file
@@ -0,0 +1 @@
|
||||
0 is no event, 1 is "Week 1 Timestamp (broken), 2 is "Week 2 Timestamp (broken), 3 is Diva Defense
|
||||
BIN
Erupe/Gifts/Cadeaux.bin
Normal file
BIN
Erupe/Gifts/Cadeaux.bin
Normal file
Binary file not shown.
BIN
Erupe/Gifts/Description.bin
Normal file
BIN
Erupe/Gifts/Description.bin
Normal file
Binary file not shown.
21
Erupe/LICENSE
Normal file
21
Erupe/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2019 The Erupe Developers from Einherjar Team
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
83
Erupe/README.md
Normal file
83
Erupe/README.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# Erupe
|
||||
## WARNING
|
||||
This project is in its infancy and has no reliable active developer, no documentation, and no support.
|
||||
|
||||
# General info
|
||||
Currently allows a JP MHF client (with GameGuard removed) to:
|
||||
* Login and register an account (registration is automatic if account doesn't exist)
|
||||
* Create a character
|
||||
* Get ingame to the main city
|
||||
* See other players walk around
|
||||
* Do quests
|
||||
* Use chat*
|
||||
|
||||
# Installation
|
||||
## Server
|
||||
1. Clone the repo with `git clone https://github.com/Andoryuuta/Erupe.git`
|
||||
2. Install PostgreSQL
|
||||
3. Launch psql shell, `CREATE DATABASE erupe;`.
|
||||
4. Setup database with golang-migrate:
|
||||
|
||||
Windows:
|
||||
```
|
||||
> go get -tags 'postgres' -u github.com/golang-migrate/migrate/v4/cmd/migrate/
|
||||
|
||||
> set POSTGRESQL_URL=postgres://postgres:password@localhost:5432/erupe?sslmode=disable
|
||||
|
||||
> cd erupe
|
||||
|
||||
> migrate -database %POSTGRESQL_URL% -path migrations up
|
||||
```
|
||||
|
||||
Linux:
|
||||
```
|
||||
> go get -tags 'postgres' -u github.com/golang-migrate/migrate/v4/cmd/migrate/
|
||||
|
||||
> export POSTGRESQL_URL=postgres://postgres:password@localhost:5432/erupe?sslmode=disable
|
||||
|
||||
> cd erupe
|
||||
|
||||
> migrate -database $POSTGRESQL_URL -path migrations up
|
||||
```
|
||||
|
||||
(Replacing `postgres:password` with your postgres username and password)
|
||||
|
||||
5. Edit the config.json
|
||||
|
||||
Namely:
|
||||
* Update the database username and password
|
||||
* Update the `host_ip` and `ip` fields (there are multiple) to your external IP if you are hosting for multiple clients.
|
||||
|
||||
6. Place quest/scenario binaries.
|
||||
|
||||
The quest and scenario binary files should be placed in `bin/quests/` and `bin/scenarios` respectively.
|
||||
|
||||
## Launcher
|
||||
Erupe ships with a rudimentary custom launcher, so you don't need to obtain the original TW/JP files to simply get ingame. However, it does still support using the original files if you choose to. To set this up, place a copy of the original launcher html/js/css in `./www/tw/`, and `/www/jp/` for the TW and JP files respectively.
|
||||
|
||||
Then, modify the the `/launcher/js/launcher.js` file as such:
|
||||
* Find the call to `startUpdateProcess();` in a case statement and replace it with `finishUpdateProcess();`. (This disables the file check and updating)
|
||||
* (JP ONLY): replace all uses of "https://" with "http://" in the file.
|
||||
|
||||
Finally, edit the config.json and set `UseOriginalLauncherFiles` to `true` under the launcher settings.
|
||||
|
||||
# Usage
|
||||
### Note: If you are switching to/from the custom launcher html, you will have to clear your IE cache @ `C:\Users\<user>\AppData\Local\Microsoft\Windows\INetCache`.
|
||||
|
||||
## Server
|
||||
```
|
||||
cd Erupe
|
||||
go run .
|
||||
```
|
||||
|
||||
## Client
|
||||
Add to hosts:
|
||||
```
|
||||
127.0.0.1 mhfg.capcom.com.tw
|
||||
127.0.0.1 mhf-n.capcom.com.tw
|
||||
127.0.0.1 cog-members.mhf-z.jp
|
||||
127.0.0.1 www.capcom-onlinegames.jp
|
||||
127.0.0.1 srv-mhf.capcom-networks.jp
|
||||
```
|
||||
|
||||
Run mhf.exe normally (with locale emulator or appropriate timezone).
|
||||
16
Erupe/bin/questlists/psql.txt
Normal file
16
Erupe/bin/questlists/psql.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE questlists (
|
||||
ind int NOT NULL PRIMARY KEY,
|
||||
questlist bytea
|
||||
);
|
||||
|
||||
END;
|
||||
|
||||
INSERT INTO questlists (ind, questlist) VALUES ('0', pg_read_binary_file('c:\save\quest_0_0.bin'));
|
||||
INSERT INTO questlists (ind, questlist) VALUES ('42', pg_read_binary_file('c:\save\quest_42_2A.bin'));
|
||||
INSERT INTO questlists (ind, questlist) VALUES ('84', pg_read_binary_file('c:\save\quest_84_54.bin'));
|
||||
INSERT INTO questlists (ind, questlist) VALUES ('126', pg_read_binary_file('c:\save\quest_126_7E.bin'));
|
||||
INSERT INTO questlists (ind, questlist) VALUES ('168', pg_read_binary_file('c:\save\quest_168_A8.bin'));
|
||||
|
||||
|
||||
8
Erupe/common/bfutil/bfutil.go
Normal file
8
Erupe/common/bfutil/bfutil.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package bfutil
|
||||
|
||||
import "bytes"
|
||||
|
||||
// UpToNull returns the given byte slice's data, up to (not including) the first null byte.
|
||||
func UpToNull(data []byte) []byte {
|
||||
return bytes.SplitN(data, []byte{0x00}, 2)[0]
|
||||
}
|
||||
40
Erupe/common/stringstack/stringstack.go
Normal file
40
Erupe/common/stringstack/stringstack.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package stringstack
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// StringStack is a basic LIFO "stack" for storing strings.
|
||||
type StringStack struct {
|
||||
sync.Mutex
|
||||
stack []string
|
||||
}
|
||||
|
||||
// New creates a new instance of StringStack
|
||||
func New() *StringStack {
|
||||
return &StringStack{}
|
||||
}
|
||||
|
||||
// Push pushes a string onto the stack.
|
||||
func (s *StringStack) Push(v string) {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
s.stack = append(s.stack, v)
|
||||
}
|
||||
|
||||
// Pop pops a string from the stack.
|
||||
func (s *StringStack) Pop() (string, error) {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
if len(s.stack) == 0 {
|
||||
return "", errors.New("no items on stack")
|
||||
}
|
||||
|
||||
x := s.stack[len(s.stack)-1]
|
||||
s.stack = s.stack[:len(s.stack)-1]
|
||||
|
||||
return x, nil
|
||||
}
|
||||
93
Erupe/common/stringsupport/string_convert.go
Normal file
93
Erupe/common/stringsupport/string_convert.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package stringsupport
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
|
||||
"golang.org/x/text/encoding"
|
||||
"golang.org/x/text/encoding/japanese"
|
||||
"golang.org/x/text/transform"
|
||||
)
|
||||
|
||||
// StringConverter is a small helper for encoding/decoding strings.
|
||||
type StringConverter struct {
|
||||
Encoding encoding.Encoding
|
||||
}
|
||||
|
||||
// Decode decodes the given bytes as the set encoding.
|
||||
func (sc *StringConverter) Decode(data []byte) (string, error) {
|
||||
decoded, err := ioutil.ReadAll(transform.NewReader(bytes.NewBuffer(data), sc.Encoding.NewDecoder()))
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(decoded), nil
|
||||
}
|
||||
|
||||
// MustDecode decodes the given bytes as the set encoding. Panics on decode failure.
|
||||
func (sc *StringConverter) MustDecode(data []byte) string {
|
||||
decoded, err := sc.Decode(data)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return decoded
|
||||
}
|
||||
|
||||
// Encode encodes the given string as the set encoding.
|
||||
func (sc *StringConverter) Encode(data string) ([]byte, error) {
|
||||
encoded, err := ioutil.ReadAll(transform.NewReader(bytes.NewBuffer([]byte(data)), sc.Encoding.NewEncoder()))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return encoded, nil
|
||||
}
|
||||
|
||||
// MustEncode encodes the given string as the set encoding. Panics on encode failure.
|
||||
func (sc *StringConverter) MustEncode(data string) []byte {
|
||||
encoded, err := sc.Encode(data)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return encoded
|
||||
}
|
||||
|
||||
/*
|
||||
func MustConvertShiftJISToUTF8(text string) string {
|
||||
result, err := ConvertShiftJISToUTF8(text)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return result
|
||||
}
|
||||
func MustConvertUTF8ToShiftJIS(text string) string {
|
||||
result, err := ConvertUTF8ToShiftJIS(text)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return result
|
||||
}
|
||||
func ConvertShiftJISToUTF8(text string) (string, error) {
|
||||
r := bytes.NewBuffer([]byte(text))
|
||||
decoded, err := ioutil.ReadAll(transform.NewReader(r, japanese.ShiftJIS.NewDecoder()))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(decoded), nil
|
||||
}
|
||||
*/
|
||||
|
||||
// ConvertUTF8ToShiftJIS converts a UTF8 string to a Shift-JIS []byte.
|
||||
func ConvertUTF8ToShiftJIS(text string) ([]byte, error) {
|
||||
r := bytes.NewBuffer([]byte(text))
|
||||
encoded, err := ioutil.ReadAll(transform.NewReader(r, japanese.ShiftJIS.NewEncoder()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return encoded, nil
|
||||
}
|
||||
153
Erupe/config.json
Normal file
153
Erupe/config.json
Normal file
@@ -0,0 +1,153 @@
|
||||
{
|
||||
"host_ip": "",
|
||||
"bin_path": "bin",
|
||||
"devmode": true,
|
||||
"devmodeoptions": {
|
||||
"serverName" : "",
|
||||
"cleandb": false,
|
||||
"maxlauncherhr": true,
|
||||
"LogOutboundMessages": false,
|
||||
"Event": 0,
|
||||
"OpcodeMessages": false,
|
||||
"SaveDumps": {
|
||||
"Enabled": true,
|
||||
"OutputDir": "savedata"
|
||||
}
|
||||
|
||||
},
|
||||
"discord": {
|
||||
"enabled": false,
|
||||
"bottoken": "",
|
||||
"channelid": ""
|
||||
},
|
||||
"database": {
|
||||
"host": "localhost",
|
||||
"port": 5432,
|
||||
"user": "postgres",
|
||||
"password": "",
|
||||
"database": "erupe"
|
||||
},
|
||||
"launcher": {
|
||||
"port": 80,
|
||||
"UseOriginalLauncherFiles": false
|
||||
},
|
||||
"sign": {
|
||||
"port": 53312
|
||||
},
|
||||
"channel": {
|
||||
"port1": 54001,
|
||||
"port2": 54002,
|
||||
"port3": 54003,
|
||||
"port4": 54004
|
||||
},
|
||||
"entrance": {
|
||||
"port": 53310,
|
||||
"entries": [
|
||||
{
|
||||
"name": " Server #1",
|
||||
"ip": "",
|
||||
"unk2": 0,
|
||||
"type": 3,
|
||||
"season": 3,
|
||||
"unk6": 0,
|
||||
"allowedclientflags": "4096",
|
||||
"channels": [
|
||||
{
|
||||
"port": 54001,
|
||||
"MaxPlayers": 100,
|
||||
"CurrentPlayers": 0,
|
||||
"Unk4": 0,
|
||||
"Unk5": 0,
|
||||
"Unk6": 0,
|
||||
"Unk7": 0,
|
||||
"Unk8": 0,
|
||||
"Unk9": 0,
|
||||
"Unk10": 319,
|
||||
"Unk11": 248,
|
||||
"Unk12": 159,
|
||||
"Unk13": 12345
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": " Server #2",
|
||||
"ip": "",
|
||||
"unk2": 0,
|
||||
"type": 1,
|
||||
"season": 3,
|
||||
"unk6": 0,
|
||||
"allowedclientflags": 0,
|
||||
"channels": [
|
||||
{
|
||||
"port": 54002,
|
||||
"MaxPlayers": 50,
|
||||
"CurrentPlayers": 0,
|
||||
"Unk4": 0,
|
||||
"Unk5": 0,
|
||||
"Unk6": 0,
|
||||
"Unk7": 0,
|
||||
"Unk8": 0,
|
||||
"Unk9": 0,
|
||||
"Unk10": 318,
|
||||
"Unk11": 251,
|
||||
"Unk12": 155,
|
||||
"Unk13": 12345
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": " Server #3",
|
||||
"ip": "",
|
||||
"unk2": 0,
|
||||
"type": 2,
|
||||
"season": 1,
|
||||
"unk6": 0,
|
||||
"allowedclientflags": 0,
|
||||
"channels": [
|
||||
{
|
||||
"port": 54003,
|
||||
"MaxPlayers": 50,
|
||||
"CurrentPlayers": 0,
|
||||
"Unk4": 0,
|
||||
"Unk5": 0,
|
||||
"Unk6": 0,
|
||||
"Unk7": 0,
|
||||
"Unk8": 0,
|
||||
"Unk9": 0,
|
||||
"Unk10": 318,
|
||||
"Unk11": 251,
|
||||
"Unk12": 155,
|
||||
"Unk13": 12345
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": " Server #4",
|
||||
"ip": "",
|
||||
"unk2": 0,
|
||||
"type": 4,
|
||||
"season": 0,
|
||||
"unk6": 0,
|
||||
"allowedclientflags": 0,
|
||||
"channels": [
|
||||
{
|
||||
"port": 54004,
|
||||
"MaxPlayers": 50,
|
||||
"CurrentPlayers": 0,
|
||||
"Unk4": 0,
|
||||
"Unk5": 0,
|
||||
"Unk6": 0,
|
||||
"Unk7": 0,
|
||||
"Unk8": 0,
|
||||
"Unk9": 0,
|
||||
"Unk10": 318,
|
||||
"Unk11": 251,
|
||||
"Unk12": 155,
|
||||
"Unk13": 12345
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
157
Erupe/config/config.go
Normal file
157
Erupe/config/config.go
Normal file
@@ -0,0 +1,157 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
// Config holds the global server-wide config.
|
||||
type Config struct {
|
||||
HostIP string `mapstructure:"host_ip"`
|
||||
BinPath string `mapstructure:"bin_path"`
|
||||
DevMode bool
|
||||
|
||||
DevModeOptions DevModeOptions
|
||||
Discord Discord
|
||||
Database Database
|
||||
Launcher Launcher
|
||||
Sign Sign
|
||||
Channel Channel
|
||||
Entrance Entrance
|
||||
}
|
||||
|
||||
// DevModeOptions holds various debug/temporary options for use while developing Erupe.
|
||||
type DevModeOptions struct {
|
||||
ServerName string // To get specific instance server about (Current Players/Event Week)
|
||||
CleanDB bool // Automatically wipes the DB on server reset.
|
||||
MaxLauncherHR bool // Sets the HR returned in the launcher to HR9 so that you can join non-beginner worlds.
|
||||
FixedStageID bool // Causes all move_stage to use the ID sl1Ns200p0a0u0 to get you into all stages
|
||||
LogOutboundMessages bool // Log all messages sent to the clients
|
||||
Event int // Changes the current event
|
||||
OpcodeMessages bool // Get all message for Opcodes
|
||||
SaveDumps SaveDumpOptions
|
||||
}
|
||||
|
||||
type SaveDumpOptions struct {
|
||||
Enabled bool
|
||||
OutputDir string
|
||||
}
|
||||
|
||||
// Discord holds the discord integration config.
|
||||
type Discord struct {
|
||||
Enabled bool
|
||||
BotToken string
|
||||
ChannelID string
|
||||
}
|
||||
|
||||
// Database holds the postgres database config.
|
||||
type Database struct {
|
||||
Host string
|
||||
Port int
|
||||
User string
|
||||
Password string
|
||||
Database string
|
||||
}
|
||||
|
||||
// Launcher holds the launcher server config.
|
||||
type Launcher struct {
|
||||
Port int
|
||||
UseOriginalLauncherFiles bool
|
||||
}
|
||||
|
||||
// Sign holds the sign server config.
|
||||
type Sign struct {
|
||||
Port int
|
||||
}
|
||||
|
||||
// Channel holds the channel server config.
|
||||
type Channel struct {
|
||||
Port1 int
|
||||
Port2 int
|
||||
Port3 int
|
||||
Port4 int
|
||||
}
|
||||
|
||||
// Entrance holds the entrance server config.
|
||||
type Entrance struct {
|
||||
Port uint16
|
||||
Entries []EntranceServerInfo
|
||||
}
|
||||
|
||||
// EntranceServerInfo represents an entry in the serverlist.
|
||||
type EntranceServerInfo struct {
|
||||
IP string
|
||||
Unk2 uint16
|
||||
Type uint8 // Server type. 0=?, 1=open, 2=cities, 3=newbie, 4=bar
|
||||
Season uint8 // Server activity. 0 = green, 1 = orange, 2 = blue
|
||||
Unk6 uint8 // Something to do with server recommendation on 0, 3, and 5.
|
||||
Name string // Server name, 66 byte null terminated Shift-JIS(JP) or Big5(TW).
|
||||
|
||||
// 4096(PC, PS3/PS4)?, 8258(PC, PS3/PS4)?, 8192 == nothing?
|
||||
// THIS ONLY EXISTS IF Binary8Header.type == "SV2", NOT "SVR"!
|
||||
AllowedClientFlags uint32
|
||||
|
||||
Channels []EntranceChannelInfo
|
||||
}
|
||||
|
||||
// EntranceChannelInfo represents an entry in a server's channel list.
|
||||
type EntranceChannelInfo struct {
|
||||
Port uint16
|
||||
MaxPlayers uint16
|
||||
CurrentPlayers uint16
|
||||
Unk4 uint16
|
||||
Unk5 uint16
|
||||
Unk6 uint16
|
||||
Unk7 uint16
|
||||
Unk8 uint16
|
||||
Unk9 uint16
|
||||
Unk10 uint16
|
||||
Unk11 uint16
|
||||
Unk12 uint16
|
||||
Unk13 uint16
|
||||
}
|
||||
|
||||
// getOutboundIP4 gets the preferred outbound ip4 of this machine
|
||||
// From https://stackoverflow.com/a/37382208
|
||||
func getOutboundIP4() net.IP {
|
||||
conn, err := net.Dial("udp4", "8.8.8.8:80")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
localAddr := conn.LocalAddr().(*net.UDPAddr)
|
||||
|
||||
return localAddr.IP.To4()
|
||||
}
|
||||
|
||||
// LoadConfig loads the given config toml file.
|
||||
func LoadConfig() (*Config, error) {
|
||||
viper.SetConfigName("config")
|
||||
viper.AddConfigPath(".")
|
||||
|
||||
viper.SetDefault("DevModeOptions.SaveDumps", SaveDumpOptions{
|
||||
Enabled: false,
|
||||
OutputDir: "savedata",
|
||||
})
|
||||
|
||||
err := viper.ReadInConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c := &Config{}
|
||||
err = viper.Unmarshal(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if c.HostIP == "" {
|
||||
c.HostIP = getOutboundIP4().To4().String()
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
75
Erupe/go.mod
Normal file
75
Erupe/go.mod
Normal file
@@ -0,0 +1,75 @@
|
||||
module github.com/Solenataris/Erupe
|
||||
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.98.0 // indirect
|
||||
cloud.google.com/go/spanner v1.27.0 // indirect
|
||||
cloud.google.com/go/storage v1.18.2 // indirect
|
||||
github.com/Andoryuuta/byteframe v0.0.0-20200114030334-8979c5cc4c4a
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.17 // indirect
|
||||
github.com/ClickHouse/clickhouse-go v1.5.1 // indirect
|
||||
github.com/apache/arrow/go/arrow v0.0.0-20211112161151-bc219186db40 // indirect
|
||||
github.com/aws/aws-sdk-go v1.42.19 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.7.4 // indirect
|
||||
github.com/bwmarrin/discordgo v0.23.2
|
||||
github.com/cenkalti/backoff/v4 v4.1.2 // indirect
|
||||
github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490 // indirect
|
||||
github.com/cockroachdb/cockroach-go/v2 v2.2.4 // indirect
|
||||
github.com/cznic/mathutil v0.0.0-20181122101859-297441e03548 // indirect
|
||||
github.com/denisenkom/go-mssqldb v0.11.0 // indirect
|
||||
github.com/envoyproxy/go-control-plane v0.10.1 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v0.6.2 // indirect
|
||||
github.com/go-sql-driver/mysql v1.6.0 // indirect
|
||||
github.com/go-stack/stack v1.8.1 // indirect
|
||||
github.com/gocql/gocql v0.0.0-20211015133455-b225f9b53fa1 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.2.0 // indirect
|
||||
github.com/golang-migrate/migrate/v4 v4.15.1 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/mock v1.6.0 // indirect
|
||||
github.com/google/go-github/v35 v35.3.0 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/gorilla/handlers v1.5.1
|
||||
github.com/gorilla/mux v1.8.0
|
||||
github.com/gorilla/websocket v1.4.2 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.0 // indirect
|
||||
github.com/jackc/pgx/v4 v4.14.1 // indirect
|
||||
github.com/jmoiron/sqlx v1.3.4
|
||||
github.com/k0kubun/pp v3.0.1+incompatible // indirect
|
||||
github.com/ktrysmt/go-bitbucket v0.9.32 // indirect
|
||||
github.com/lib/pq v1.10.4
|
||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible // indirect
|
||||
github.com/mitchellh/mapstructure v1.4.3 // indirect
|
||||
github.com/mutecomm/go-sqlcipher/v4 v4.4.2 // indirect
|
||||
github.com/nakagami/firebirdsql v0.9.3 // indirect
|
||||
github.com/neo4j/neo4j-go-driver v1.8.3 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.12 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/sachaos/lottery v0.0.0-20180520074626-61949d99bd96
|
||||
github.com/shopspring/decimal v1.3.1 // indirect
|
||||
github.com/snowflakedb/gosnowflake v1.6.4 // indirect
|
||||
github.com/spf13/viper v1.8.1
|
||||
github.com/xanzy/go-gitlab v0.52.2 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
|
||||
go.mongodb.org/mongo-driver v1.8.0 // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.7.0 // indirect
|
||||
go.uber.org/zap v1.18.1
|
||||
golang.org/x/crypto v0.0.0-20211202192323-5770296d904e
|
||||
golang.org/x/net v0.0.0-20211205041911-012df41ee64c // indirect
|
||||
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d // indirect
|
||||
golang.org/x/text v0.3.7
|
||||
golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 // indirect
|
||||
golang.org/x/tools v0.1.8 // indirect
|
||||
google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0 // indirect
|
||||
google.golang.org/grpc v1.42.0 // indirect
|
||||
modernc.org/ccgo/v3 v3.12.86 // indirect
|
||||
modernc.org/ql v1.4.0 // indirect
|
||||
modernc.org/sqlite v1.14.2 // indirect
|
||||
)
|
||||
1972
Erupe/go.sum
Normal file
1972
Erupe/go.sum
Normal file
File diff suppressed because it is too large
Load Diff
177
Erupe/main.go
Normal file
177
Erupe/main.go
Normal file
@@ -0,0 +1,177 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/Solenataris/Erupe/config"
|
||||
"github.com/Solenataris/Erupe/server/channelserver"
|
||||
"github.com/Solenataris/Erupe/server/entranceserver"
|
||||
"github.com/Solenataris/Erupe/server/launcherserver"
|
||||
"github.com/Solenataris/Erupe/server/signserver"
|
||||
"github.com/jmoiron/sqlx"
|
||||
_ "github.com/lib/pq"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
// Temporary DB auto clean on startup for quick development & testing.
|
||||
func cleanDB(db *sqlx.DB) {
|
||||
_ = db.MustExec("DELETE FROM guild_characters")
|
||||
_ = db.MustExec("DELETE FROM guilds")
|
||||
_ = db.MustExec("DELETE FROM characters")
|
||||
_ = db.MustExec("DELETE FROM sign_sessions")
|
||||
_ = db.MustExec("DELETE FROM users")
|
||||
}
|
||||
|
||||
func main() {
|
||||
zapLogger, _ := zap.NewDevelopment()
|
||||
defer zapLogger.Sync()
|
||||
logger := zapLogger.Named("main")
|
||||
|
||||
logger.Info("Starting Erupe")
|
||||
|
||||
// Load the configuration.
|
||||
erupeConfig, err := config.LoadConfig()
|
||||
if err != nil {
|
||||
logger.Fatal("Failed to load config", zap.Error(err))
|
||||
}
|
||||
|
||||
// Create the postgres DB pool.
|
||||
connectString := fmt.Sprintf(
|
||||
"host=%s port=%d user=%s password=%s dbname= %s sslmode=disable",
|
||||
erupeConfig.Database.Host,
|
||||
erupeConfig.Database.Port,
|
||||
erupeConfig.Database.User,
|
||||
erupeConfig.Database.Password,
|
||||
erupeConfig.Database.Database,
|
||||
)
|
||||
|
||||
db, err := sqlx.Open("postgres", connectString)
|
||||
if err != nil {
|
||||
logger.Fatal("Failed to open sql database", zap.Error(err))
|
||||
}
|
||||
|
||||
// Test the DB connection.
|
||||
err = db.Ping()
|
||||
if err != nil {
|
||||
logger.Fatal("Failed to ping database", zap.Error(err))
|
||||
}
|
||||
logger.Info("Connected to database")
|
||||
|
||||
// Clean the DB if the option is on.
|
||||
if erupeConfig.DevMode && erupeConfig.DevModeOptions.CleanDB {
|
||||
logger.Info("Cleaning DB")
|
||||
cleanDB(db)
|
||||
logger.Info("Done cleaning DB")
|
||||
}
|
||||
|
||||
// Now start our server(s).
|
||||
|
||||
// Launcher HTTP server.
|
||||
launcherServer := launcherserver.NewServer(
|
||||
&launcherserver.Config{
|
||||
Logger: logger.Named("launcher"),
|
||||
ErupeConfig: erupeConfig,
|
||||
DB: db,
|
||||
UseOriginalLauncherFiles: erupeConfig.Launcher.UseOriginalLauncherFiles,
|
||||
})
|
||||
err = launcherServer.Start()
|
||||
if err != nil {
|
||||
logger.Fatal("Failed to start launcher server", zap.Error(err))
|
||||
}
|
||||
logger.Info("Started launcher server.")
|
||||
|
||||
// Entrance server.
|
||||
entranceServer := entranceserver.NewServer(
|
||||
&entranceserver.Config{
|
||||
Logger: logger.Named("entrance"),
|
||||
ErupeConfig: erupeConfig,
|
||||
DB: db,
|
||||
})
|
||||
err = entranceServer.Start()
|
||||
if err != nil {
|
||||
logger.Fatal("Failed to start entrance server", zap.Error(err))
|
||||
}
|
||||
logger.Info("Started entrance server.")
|
||||
|
||||
// Sign server.
|
||||
signServer := signserver.NewServer(
|
||||
&signserver.Config{
|
||||
Logger: logger.Named("sign"),
|
||||
ErupeConfig: erupeConfig,
|
||||
DB: db,
|
||||
})
|
||||
err = signServer.Start()
|
||||
if err != nil {
|
||||
logger.Fatal("Failed to start sign server", zap.Error(err))
|
||||
}
|
||||
logger.Info("Started sign server.")
|
||||
|
||||
// Channel Server
|
||||
channelServer1 := channelserver.NewServer(
|
||||
&channelserver.Config{
|
||||
Logger: logger.Named("channel"),
|
||||
ErupeConfig: erupeConfig,
|
||||
DB: db,
|
||||
})
|
||||
|
||||
err = channelServer1.Start(erupeConfig.Channel.Port1)
|
||||
if err != nil {
|
||||
logger.Fatal("Failed to start channel server1", zap.Error(err))
|
||||
}
|
||||
logger.Info("Started channel server.")
|
||||
// Channel Server
|
||||
channelServer2 := channelserver.NewServer(
|
||||
&channelserver.Config{
|
||||
Logger: logger.Named("channel"),
|
||||
ErupeConfig: erupeConfig,
|
||||
DB: db,
|
||||
})
|
||||
|
||||
err = channelServer2.Start(erupeConfig.Channel.Port2)
|
||||
if err != nil {
|
||||
logger.Fatal("Failed to start channel server2", zap.Error(err))
|
||||
}
|
||||
// Channel Server
|
||||
channelServer3 := channelserver.NewServer(
|
||||
&channelserver.Config{
|
||||
Logger: logger.Named("channel"),
|
||||
ErupeConfig: erupeConfig,
|
||||
DB: db,
|
||||
})
|
||||
|
||||
err = channelServer3.Start(erupeConfig.Channel.Port3)
|
||||
if err != nil {
|
||||
logger.Fatal("Failed to start channel server3", zap.Error(err))
|
||||
}
|
||||
// Channel Server
|
||||
channelServer4 := channelserver.NewServer(
|
||||
&channelserver.Config{
|
||||
Logger: logger.Named("channel"),
|
||||
ErupeConfig: erupeConfig,
|
||||
DB: db,
|
||||
})
|
||||
|
||||
err = channelServer4.Start(erupeConfig.Channel.Port4)
|
||||
if err != nil {
|
||||
logger.Fatal("Failed to start channel server4", zap.Error(err))
|
||||
}
|
||||
// Wait for exit or interrupt with ctrl+C.
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
||||
<-c
|
||||
|
||||
logger.Info("Trying to shutdown gracefully.")
|
||||
channelServer4.Shutdown()
|
||||
channelServer3.Shutdown()
|
||||
channelServer2.Shutdown()
|
||||
channelServer1.Shutdown()
|
||||
signServer.Shutdown()
|
||||
entranceServer.Shutdown()
|
||||
launcherServer.Shutdown()
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
10
Erupe/migrations/000001_initial_db.down.sql
Normal file
10
Erupe/migrations/000001_initial_db.down.sql
Normal file
@@ -0,0 +1,10 @@
|
||||
BEGIN;
|
||||
|
||||
DROP TABLE IF EXISTS sign_sessions;
|
||||
DROP TABLE IF EXISTS characters;
|
||||
DROP TABLE IF EXISTS users;
|
||||
|
||||
DROP DOMAIN IF EXISTS uint8;
|
||||
DROP DOMAIN IF EXISTS uint16;
|
||||
|
||||
END;
|
||||
36
Erupe/migrations/000001_initial_db.up.sql
Normal file
36
Erupe/migrations/000001_initial_db.up.sql
Normal file
@@ -0,0 +1,36 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE DOMAIN uint8 AS smallint
|
||||
CHECK(VALUE >= 0 AND VALUE <= 255);
|
||||
|
||||
CREATE DOMAIN uint16 AS integer
|
||||
CHECK(VALUE >= 0 AND VALUE <= 65536);
|
||||
|
||||
CREATE TABLE users (
|
||||
id serial NOT NULL PRIMARY KEY,
|
||||
username text UNIQUE NOT NULL,
|
||||
password text NOT NULL
|
||||
);
|
||||
|
||||
CREATE TABLE characters (
|
||||
id serial NOT NULL PRIMARY KEY,
|
||||
user_id bigint REFERENCES users(id),
|
||||
is_female boolean,
|
||||
is_new_character boolean,
|
||||
small_gr_level uint8,
|
||||
gr_override_mode boolean,
|
||||
name varchar(15),
|
||||
unk_desc_string varchar(31),
|
||||
gr_override_level uint16,
|
||||
gr_override_unk0 uint8,
|
||||
gr_override_unk1 uint8
|
||||
);
|
||||
|
||||
CREATE TABLE sign_sessions (
|
||||
id serial NOT NULL PRIMARY KEY,
|
||||
user_id bigint REFERENCES users(id),
|
||||
auth_token_num bigint,
|
||||
auth_token_str text
|
||||
);
|
||||
|
||||
END;
|
||||
8
Erupe/migrations/000002_alter_characters.down.sql
Normal file
8
Erupe/migrations/000002_alter_characters.down.sql
Normal file
@@ -0,0 +1,8 @@
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE characters
|
||||
DROP COLUMN exp,
|
||||
DROP COLUMN weapon,
|
||||
DROP COLUMN last_login;
|
||||
|
||||
END;
|
||||
8
Erupe/migrations/000002_alter_characters.up.sql
Normal file
8
Erupe/migrations/000002_alter_characters.up.sql
Normal file
@@ -0,0 +1,8 @@
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE characters
|
||||
ADD COLUMN exp uint16,
|
||||
ADD COLUMN weapon uint16,
|
||||
ADD COLUMN last_login integer;
|
||||
|
||||
END;
|
||||
6
Erupe/migrations/000003_character_savedata.down.sql
Normal file
6
Erupe/migrations/000003_character_savedata.down.sql
Normal file
@@ -0,0 +1,6 @@
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE characters
|
||||
DROP COLUMN savedata;
|
||||
|
||||
END;
|
||||
6
Erupe/migrations/000003_character_savedata.up.sql
Normal file
6
Erupe/migrations/000003_character_savedata.up.sql
Normal file
@@ -0,0 +1,6 @@
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE characters
|
||||
ADD COLUMN savedata bytea;
|
||||
|
||||
END;
|
||||
13
Erupe/migrations/000004_character_additional.down.sql
Normal file
13
Erupe/migrations/000004_character_additional.down.sql
Normal file
@@ -0,0 +1,13 @@
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE characters
|
||||
DROP COLUMN decomyset,
|
||||
DROP COLUMN hunternavi,
|
||||
DROP COLUMN otomoairou,
|
||||
DROP COLUMN partner,
|
||||
DROP COLUMN platebox,
|
||||
DROP COLUMN platedata,
|
||||
DROP COLUMN platemyset,
|
||||
DROP COLUMN rengokudata;
|
||||
|
||||
END;
|
||||
14
Erupe/migrations/000004_character_additional.up.sql
Normal file
14
Erupe/migrations/000004_character_additional.up.sql
Normal file
@@ -0,0 +1,14 @@
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE characters
|
||||
ADD COLUMN decomyset bytea,
|
||||
ADD COLUMN hunternavi bytea,
|
||||
ADD COLUMN otomoairou bytea,
|
||||
ADD COLUMN partner bytea,
|
||||
ADD COLUMN platebox bytea,
|
||||
ADD COLUMN platedata bytea,
|
||||
ADD COLUMN platemyset bytea,
|
||||
ADD COLUMN trophy bytea,
|
||||
ADD COLUMN rengokudata bytea;
|
||||
|
||||
END;
|
||||
5
Erupe/migrations/000005_quests.down.sql
Normal file
5
Erupe/migrations/000005_quests.down.sql
Normal file
@@ -0,0 +1,5 @@
|
||||
BEGIN;
|
||||
|
||||
DROP TABLE IF EXISTS questlists;
|
||||
|
||||
END;
|
||||
8
Erupe/migrations/000005_quests.up.sql
Normal file
8
Erupe/migrations/000005_quests.up.sql
Normal file
@@ -0,0 +1,8 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE questlists (
|
||||
ind int NOT NULL PRIMARY KEY,
|
||||
questlist bytea
|
||||
);
|
||||
|
||||
END;
|
||||
6
Erupe/migrations/000006_mercenary.down.sql
Normal file
6
Erupe/migrations/000006_mercenary.down.sql
Normal file
@@ -0,0 +1,6 @@
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE characters
|
||||
DROP COLUMN savemercenary;
|
||||
|
||||
END;
|
||||
6
Erupe/migrations/000006_mercenary.up.sql
Normal file
6
Erupe/migrations/000006_mercenary.up.sql
Normal file
@@ -0,0 +1,6 @@
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE characters
|
||||
ADD COLUMN savemercenary bytea;
|
||||
|
||||
END;
|
||||
6
Erupe/migrations/000007_guilds.down.sql
Normal file
6
Erupe/migrations/000007_guilds.down.sql
Normal file
@@ -0,0 +1,6 @@
|
||||
BEGIN;
|
||||
|
||||
DROP TABLE guild_characters;
|
||||
DROP TABLE guilds;
|
||||
|
||||
END;
|
||||
22
Erupe/migrations/000007_guilds.up.sql
Normal file
22
Erupe/migrations/000007_guilds.up.sql
Normal file
@@ -0,0 +1,22 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE guilds
|
||||
(
|
||||
id serial NOT NULL PRIMARY KEY,
|
||||
name varchar(24),
|
||||
created_at timestamp DEFAULT NOW(),
|
||||
leader_id int NOT NULL,
|
||||
main_motto varchar(255) DEFAULT ''
|
||||
);
|
||||
|
||||
CREATE TABLE guild_characters
|
||||
(
|
||||
id serial NOT NULL PRIMARY KEY,
|
||||
guild_id bigint REFERENCES guilds (id),
|
||||
character_id bigint REFERENCES characters (id),
|
||||
joined_at timestamp DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX guild_character_unique_index ON guild_characters (character_id);
|
||||
|
||||
END;
|
||||
11
Erupe/migrations/000008_guild_additional.down.sql
Normal file
11
Erupe/migrations/000008_guild_additional.down.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE guilds
|
||||
DROP COLUMN rp;
|
||||
|
||||
ALTER TABLE guild_characters
|
||||
DROP COLUMN is_applicant,
|
||||
DROP COLUMN is_sub_leader,
|
||||
DROP COLUMN order_index;
|
||||
|
||||
END;
|
||||
11
Erupe/migrations/000008_guild_additional.up.sql
Normal file
11
Erupe/migrations/000008_guild_additional.up.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE guild_characters
|
||||
ADD COLUMN is_applicant bool NOT NULL DEFAULT false,
|
||||
ADD COLUMN is_sub_leader bool NOT NULL DEFAULT false,
|
||||
ADD COLUMN order_index int NOT NULL DEFAULT 1;
|
||||
|
||||
ALTER TABLE guilds
|
||||
ADD COLUMN rp uint16 NOT NULL DEFAULT 0;
|
||||
|
||||
END;
|
||||
6
Erupe/migrations/000009_character_social.down.sql
Normal file
6
Erupe/migrations/000009_character_social.down.sql
Normal file
@@ -0,0 +1,6 @@
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE characters
|
||||
DROP COLUMN restrict_guild_scout;
|
||||
|
||||
END;
|
||||
6
Erupe/migrations/000009_character_social.up.sql
Normal file
6
Erupe/migrations/000009_character_social.up.sql
Normal file
@@ -0,0 +1,6 @@
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE characters
|
||||
ADD COLUMN restrict_guild_scout bool NOT NULL DEFAULT false;
|
||||
|
||||
END;
|
||||
@@ -0,0 +1,10 @@
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE guilds
|
||||
DROP COLUMN comment,
|
||||
DROP COLUMN festival_colour,
|
||||
DROP COLUMN guild_hall;
|
||||
|
||||
DROP TYPE festival_colour;
|
||||
|
||||
END;
|
||||
11
Erupe/migrations/000010_guild_comments_festival_hall.up.sql
Normal file
11
Erupe/migrations/000010_guild_comments_festival_hall.up.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TYPE festival_colour AS ENUM ('none', 'red', 'blue');
|
||||
|
||||
ALTER TABLE guilds
|
||||
ADD COLUMN comment varchar(255) NOT NULL DEFAULT '',
|
||||
ADD COLUMN festival_colour festival_colour DEFAULT 'none',
|
||||
ADD COLUMN guild_hall int DEFAULT 0;
|
||||
|
||||
|
||||
END;
|
||||
24
Erupe/migrations/000011_character_points_minidata.down.sql
Normal file
24
Erupe/migrations/000011_character_points_minidata.down.sql
Normal file
@@ -0,0 +1,24 @@
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE characters
|
||||
DROP COLUMN minidata,
|
||||
DROP COLUMN gacha_trial,
|
||||
DROP COLUMN gacha_prem,
|
||||
DROP COLUMN gacha_items,
|
||||
DROP COLUMN daily_time,
|
||||
DROP COLUMN frontier_points,
|
||||
DROP COLUMN netcafe_points,
|
||||
DROP COLUMN house_info,
|
||||
DROP COLUMN login_boost,
|
||||
DROP COLUMN skin_hist,
|
||||
DROP COLUMN gcp;
|
||||
|
||||
DROP TABLE fpoint_items;
|
||||
DROP TABLE gacha_shop;
|
||||
DROP TABLE gacha_shop_items;
|
||||
DROP TABLE lucky_box_state;
|
||||
DROP TABLE stepup_state;
|
||||
DROP TABLE normal_shop_items;
|
||||
DROP TABLE shop_item_state;
|
||||
|
||||
END;
|
||||
100
Erupe/migrations/000011_character_points_minidata.up.sql
Normal file
100
Erupe/migrations/000011_character_points_minidata.up.sql
Normal file
@@ -0,0 +1,100 @@
|
||||
BEGIN;
|
||||
ALTER TABLE characters
|
||||
ADD COLUMN minidata bytea,
|
||||
ADD COLUMN gacha_trial int,
|
||||
ADD COLUMN gacha_prem int,
|
||||
ADD COLUMN gacha_items bytea,
|
||||
ADD COLUMN daily_time timestamp,
|
||||
ADD COLUMN frontier_points int,
|
||||
ADD COLUMN netcafe_points int,
|
||||
ADD COLUMN house_info bytea,
|
||||
ADD COLUMN login_boost bytea,
|
||||
ADD COLUMN skin_hist bytea,
|
||||
ADD COLUMN kouryou_point int,
|
||||
ADD COLUMN gcp int;
|
||||
|
||||
CREATE TABLE fpoint_items
|
||||
(
|
||||
hash int,
|
||||
itemType uint8,
|
||||
itemID uint16,
|
||||
quant uint16,
|
||||
itemValue uint16,
|
||||
tradeType uint8
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE gacha_shop
|
||||
(
|
||||
hash bigint,
|
||||
reqGR int,
|
||||
reqHR int,
|
||||
gachaName varchar(255),
|
||||
gachaLink0 varchar(255),
|
||||
gachaLink1 varchar(255),
|
||||
gachaLink2 varchar(255),
|
||||
extraIcon int,
|
||||
gachaType int,
|
||||
hideFlag bool
|
||||
);
|
||||
|
||||
CREATE TABLE gacha_shop_items
|
||||
(
|
||||
shophash int,
|
||||
entryType uint8,
|
||||
itemhash int UNIQUE NOT NULL,
|
||||
currType uint8,
|
||||
currNumber uint16,
|
||||
currQuant uint16,
|
||||
percentage uint16,
|
||||
rarityIcon uint8,
|
||||
rollsCount uint8,
|
||||
itemCount uint8,
|
||||
dailyLimit uint8,
|
||||
itemType int[],
|
||||
itemId int[],
|
||||
quantity int[]
|
||||
);
|
||||
|
||||
CREATE TABLE lucky_box_state
|
||||
(
|
||||
char_id bigint REFERENCES characters (id),
|
||||
shophash int UNIQUE NOT NULL,
|
||||
used_itemhash int[]
|
||||
);
|
||||
|
||||
|
||||
CREATE TABLE stepup_state
|
||||
(
|
||||
char_id bigint REFERENCES characters (id),
|
||||
shophash int UNIQUE NOT NULL,
|
||||
step_progression int,
|
||||
step_time timestamp
|
||||
);
|
||||
|
||||
CREATE TABLE normal_shop_items
|
||||
(
|
||||
shoptype int,
|
||||
shopid int,
|
||||
itemhash int UNIQUE NOT NULL,
|
||||
itemID uint16,
|
||||
Points uint16,
|
||||
TradeQuantity uint16,
|
||||
rankReqLow uint16,
|
||||
rankReqHigh uint16,
|
||||
rankReqG uint16,
|
||||
storeLevelReq uint16,
|
||||
maximumQuantity uint16,
|
||||
boughtQuantity uint16,
|
||||
roadFloorsRequired uint16,
|
||||
weeklyFatalisKills uint16
|
||||
);
|
||||
|
||||
CREATE TABLE shop_item_state
|
||||
(
|
||||
char_id bigint REFERENCES characters (id),
|
||||
itemhash int UNIQUE NOT NULL,
|
||||
usedquantity int
|
||||
);
|
||||
|
||||
END;
|
||||
5
Erupe/migrations/000012_loginboost_etc.down.sql
Normal file
5
Erupe/migrations/000012_loginboost_etc.down.sql
Normal file
@@ -0,0 +1,5 @@
|
||||
BEGIN;
|
||||
|
||||
DROP TABLE login_boost_state;
|
||||
|
||||
END;
|
||||
13
Erupe/migrations/000012_loginboost_etc.up.sql
Normal file
13
Erupe/migrations/000012_loginboost_etc.up.sql
Normal file
@@ -0,0 +1,13 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE login_boost_state
|
||||
(
|
||||
char_id bigint REFERENCES characters (id),
|
||||
week_req uint8,
|
||||
week_count uint8,
|
||||
available bool,
|
||||
end_time int,
|
||||
CONSTRAINT id_week UNIQUE(char_id, week_req)
|
||||
);
|
||||
|
||||
END;
|
||||
12
Erupe/migrations/000013_shop_constraints.down.sql
Normal file
12
Erupe/migrations/000013_shop_constraints.down.sql
Normal file
@@ -0,0 +1,12 @@
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE shop_item_state DROP CONSTRAINT shop_item_state_id_itemhash;
|
||||
ALTER TABLE shop_item_state ADD CONSTRAINT shop_item_state_itemhash_key UNIQUE (itemhash);
|
||||
|
||||
ALTER TABLE stepup_state DROP CONSTRAINT stepup_state_id_shophash;
|
||||
ALTER TABLE stepup_state ADD CONSTRAINT stepup_state_shophash_key UNIQUE (shophash);
|
||||
|
||||
ALTER TABLE lucky_box_state DROP CONSTRAINT lucky_box_state_id_shophash;
|
||||
ALTER TABLE lucky_box_state ADD CONSTRAINT lucky_box_state_shophash_key UNIQUE (shophash);
|
||||
|
||||
END;
|
||||
12
Erupe/migrations/000013_shop_constraints.up.sql
Normal file
12
Erupe/migrations/000013_shop_constraints.up.sql
Normal file
@@ -0,0 +1,12 @@
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE shop_item_state DROP CONSTRAINT shop_item_state_itemhash_key;
|
||||
ALTER TABLE shop_item_state ADD CONSTRAINT shop_item_state_id_itemhash UNIQUE(char_id, itemhash);
|
||||
|
||||
ALTER TABLE stepup_state DROP CONSTRAINT stepup_state_shophash_key;
|
||||
ALTER TABLE stepup_state ADD CONSTRAINT stepup_state_id_shophash UNIQUE(char_id, shophash);
|
||||
|
||||
ALTER TABLE lucky_box_state DROP CONSTRAINT lucky_box_state_shophash_key;
|
||||
ALTER TABLE lucky_box_state ADD CONSTRAINT lucky_box_state_id_shophash UNIQUE(char_id, shophash);
|
||||
|
||||
END;
|
||||
18
Erupe/migrations/000014_guild_flags_applications.down.sql
Normal file
18
Erupe/migrations/000014_guild_flags_applications.down.sql
Normal file
@@ -0,0 +1,18 @@
|
||||
BEGIN;
|
||||
ALTER TABLE guild_characters
|
||||
RENAME COLUMN avoid_leadership TO is_sub_leader;
|
||||
|
||||
ALTER TABLE guild_characters
|
||||
ADD COLUMN is_applicant bool NOT NULL DEFAULT false;
|
||||
|
||||
ALTER TABLE guilds
|
||||
DROP COLUMN icon,
|
||||
ALTER COLUMN main_motto TYPE varchar USING '',
|
||||
DROP COLUMN sub_motto;
|
||||
|
||||
ALTER TABLE guilds
|
||||
ALTER COLUMN main_motto SET DEFAULT '';
|
||||
|
||||
DROP TABLE guild_applications;
|
||||
DROP TYPE guild_application_type;
|
||||
END;
|
||||
30
Erupe/migrations/000014_guild_flags_applications.up.sql
Normal file
30
Erupe/migrations/000014_guild_flags_applications.up.sql
Normal file
@@ -0,0 +1,30 @@
|
||||
BEGIN;
|
||||
CREATE TYPE guild_application_type AS ENUM ('applied', 'invited');
|
||||
|
||||
CREATE TABLE guild_applications
|
||||
(
|
||||
id serial NOT NULL PRIMARY KEY,
|
||||
guild_id int NOT NULL REFERENCES guilds (id),
|
||||
character_id int NOT NULL REFERENCES characters (id),
|
||||
actor_id int NOT NULL REFERENCES characters (id),
|
||||
application_type guild_application_type NOT NULL,
|
||||
created_at timestamp NOT NULL DEFAULT now(),
|
||||
CONSTRAINT guild_application_character_id UNIQUE (guild_id, character_id)
|
||||
);
|
||||
|
||||
CREATE INDEX guild_application_type_index ON guild_applications (application_type);
|
||||
|
||||
ALTER TABLE guild_characters
|
||||
DROP COLUMN is_applicant;
|
||||
|
||||
ALTER TABLE guild_characters
|
||||
RENAME COLUMN is_sub_leader TO avoid_leadership;
|
||||
|
||||
ALTER TABLE guilds
|
||||
ALTER COLUMN main_motto SET DEFAULT 0;
|
||||
|
||||
ALTER TABLE guilds
|
||||
ADD COLUMN icon bytea,
|
||||
ADD COLUMN sub_motto int DEFAULT 0,
|
||||
ALTER COLUMN main_motto TYPE int USING 0;
|
||||
END;
|
||||
3
Erupe/migrations/000015_mail.down.sql
Normal file
3
Erupe/migrations/000015_mail.down.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
BEGIN;
|
||||
DROP TABLE mail;
|
||||
END;
|
||||
19
Erupe/migrations/000015_mail.up.sql
Normal file
19
Erupe/migrations/000015_mail.up.sql
Normal file
@@ -0,0 +1,19 @@
|
||||
BEGIN;
|
||||
CREATE TABLE mail
|
||||
(
|
||||
id SERIAL NOT NULL PRIMARY KEY,
|
||||
sender_id INT NOT NULL REFERENCES characters (id),
|
||||
recipient_id INT NOT NULL REFERENCES characters (id),
|
||||
subject VARCHAR NOT NULL DEFAULT '',
|
||||
body VARCHAR NOT NULL DEFAULT '',
|
||||
read BOOL NOT NULL DEFAULT FALSE,
|
||||
attached_item_received BOOL NOT NULL DEFAULT FALSE,
|
||||
attached_item INT DEFAULT NULL,
|
||||
attached_item_amount INT NOT NULL DEFAULT 1,
|
||||
is_guild_invite BOOL NOT NULL DEFAULT FALSE,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
deleted BOOL NOT NULL DEFAULT FALSE
|
||||
);
|
||||
|
||||
CREATE INDEX mail_recipient_deleted_created_id_index ON mail (recipient_id, deleted, created_at DESC, id DESC);
|
||||
END;
|
||||
3
Erupe/migrations/000016_server.down.sql
Normal file
3
Erupe/migrations/000016_server.down.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
BEGIN;
|
||||
DROP TABLE public.servers;
|
||||
END;
|
||||
21
Erupe/migrations/000016_server.up.sql
Normal file
21
Erupe/migrations/000016_server.up.sql
Normal file
@@ -0,0 +1,21 @@
|
||||
BEGIN;
|
||||
-- Table: public.servers
|
||||
|
||||
-- DROP TABLE IF EXISTS public.servers;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS public.servers
|
||||
(
|
||||
server_id integer NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
|
||||
server_name text COLLATE pg_catalog."default",
|
||||
season integer,
|
||||
current_players integer,
|
||||
event_id integer,
|
||||
event_expiration integer,
|
||||
CONSTRAINT servers_pkey PRIMARY KEY (server_id)
|
||||
)
|
||||
|
||||
TABLESPACE pg_default;
|
||||
|
||||
ALTER TABLE IF EXISTS public.servers
|
||||
OWNER to postgres;
|
||||
END;
|
||||
6
Erupe/migrations/000017_account.down.sql
Normal file
6
Erupe/migrations/000017_account.down.sql
Normal file
@@ -0,0 +1,6 @@
|
||||
BEGIN;
|
||||
DROP TABLE public.account_ban;
|
||||
DROP TABLE public.account_history;
|
||||
DROP TABLE public.account_moderation;
|
||||
DROP TABLE public.account_sub;
|
||||
END;
|
||||
45
Erupe/migrations/000017_account.up.sql
Normal file
45
Erupe/migrations/000017_account.up.sql
Normal file
@@ -0,0 +1,45 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS public.account_ban
|
||||
(
|
||||
user_id integer NOT NULL,
|
||||
title text COLLATE pg_catalog."default",
|
||||
reason text COLLATE pg_catalog."default",
|
||||
date text COLLATE pg_catalog."default",
|
||||
pass_origin text COLLATE pg_catalog."default",
|
||||
pass_block text COLLATE pg_catalog."default",
|
||||
CONSTRAINT ban_pkey PRIMARY KEY (user_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS public.account_history
|
||||
(
|
||||
report_id integer NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
|
||||
user_id integer,
|
||||
title text COLLATE pg_catalog."default",
|
||||
reason text COLLATE pg_catalog."default",
|
||||
date date,
|
||||
CONSTRAINT account_history_pkey PRIMARY KEY (report_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS public.account_moderation
|
||||
(
|
||||
id integer NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
|
||||
username text COLLATE pg_catalog."default",
|
||||
password text COLLATE pg_catalog."default",
|
||||
type text COLLATE pg_catalog."default",
|
||||
CONSTRAINT account_moderation_pkey PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS public.account_sub
|
||||
(
|
||||
id integer NOT NULL GENERATED BY DEFAULT AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
|
||||
discord_id text COLLATE pg_catalog."default",
|
||||
erupe_account text COLLATE pg_catalog."default",
|
||||
erupe_password text COLLATE pg_catalog."default",
|
||||
date_inscription date,
|
||||
country text COLLATE pg_catalog."default",
|
||||
presentation text COLLATE pg_catalog."default",
|
||||
CONSTRAINT account_auth_pkey PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
END;
|
||||
3
Erupe/migrations/000018_event_week.down.sql
Normal file
3
Erupe/migrations/000018_event_week.down.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
BEGIN;
|
||||
DROP TABLE public.event_week;
|
||||
END;
|
||||
11
Erupe/migrations/000018_event_week.up.sql
Normal file
11
Erupe/migrations/000018_event_week.up.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS public.event_week
|
||||
(
|
||||
id integer NOT NULL,
|
||||
event_id integer NOT NULL,
|
||||
date_expiration integer NOT NULL,
|
||||
CONSTRAINT event_week_pkey PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
END;
|
||||
3
Erupe/migrations/000019_gook.down.sql
Normal file
3
Erupe/migrations/000019_gook.down.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
BEGIN;
|
||||
DROP TABLE public.gook;
|
||||
END;
|
||||
20
Erupe/migrations/000019_gook.up.sql
Normal file
20
Erupe/migrations/000019_gook.up.sql
Normal file
@@ -0,0 +1,20 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS public.gook
|
||||
(
|
||||
id serial NOT NULL PRIMARY KEY,
|
||||
gook0 bytea,
|
||||
gook1 bytea,
|
||||
gook2 bytea,
|
||||
gook3 bytea,
|
||||
gook4 bytea,
|
||||
gook5 bytea,
|
||||
gook0status boolean,
|
||||
gook1status boolean,
|
||||
gook2status boolean,
|
||||
gook3status boolean,
|
||||
gook4status boolean,
|
||||
gook5status boolean
|
||||
);
|
||||
|
||||
END;
|
||||
3
Erupe/migrations/000020_history.down.sql
Normal file
3
Erupe/migrations/000020_history.down.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
BEGIN;
|
||||
DROP TABLE public.history;
|
||||
END;
|
||||
13
Erupe/migrations/000020_history.up.sql
Normal file
13
Erupe/migrations/000020_history.up.sql
Normal file
@@ -0,0 +1,13 @@
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS public.history
|
||||
(
|
||||
user_id integer,
|
||||
admin_id integer,
|
||||
report_id integer NOT NULL,
|
||||
title text COLLATE pg_catalog."default",
|
||||
reason text COLLATE pg_catalog."default",
|
||||
CONSTRAINT history_pkey PRIMARY KEY (report_id)
|
||||
);
|
||||
|
||||
END;
|
||||
60
Erupe/network/binpacket/msg_bin_chat.go
Normal file
60
Erupe/network/binpacket/msg_bin_chat.go
Normal file
@@ -0,0 +1,60 @@
|
||||
package binpacket
|
||||
|
||||
import (
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// ChatType represents the chat message type (Thanks to @Alice on discord for identifying these!)
|
||||
type ChatType uint8
|
||||
|
||||
// Chat types
|
||||
const (
|
||||
ChatTypeLocal ChatType = 1
|
||||
ChatTypeGuild = 2
|
||||
ChatTypeAlliance = 3
|
||||
ChatTypeParty = 4
|
||||
ChatTypeWhisper = 5
|
||||
)
|
||||
|
||||
// MsgBinChat is a binpacket for chat messages.
|
||||
type MsgBinChat struct {
|
||||
Unk0 uint8
|
||||
Type ChatType
|
||||
Flags uint16
|
||||
Message string
|
||||
SenderName string
|
||||
}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgBinChat) Opcode() network.PacketID {
|
||||
return network.MSG_SYS_CAST_BINARY
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgBinChat) Parse(bf *byteframe.ByteFrame) error {
|
||||
m.Unk0 = bf.ReadUint8()
|
||||
m.Type = ChatType(bf.ReadUint8())
|
||||
m.Flags = bf.ReadUint16()
|
||||
senderNameSize := bf.ReadUint16()
|
||||
messageSize := bf.ReadUint16()
|
||||
|
||||
// TODO(Andoryuuta): Need proper shift-jis and null termination.
|
||||
m.Message = string(bf.ReadBytes(uint(messageSize))[:messageSize-1])
|
||||
m.SenderName = string(bf.ReadBytes(uint(senderNameSize))[:senderNameSize-1])
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgBinChat) Build(bf *byteframe.ByteFrame) error {
|
||||
bf.WriteUint8(m.Unk0)
|
||||
bf.WriteUint8(uint8(m.Type))
|
||||
bf.WriteUint16(m.Flags)
|
||||
bf.WriteUint16(uint16(len(m.SenderName) + 1))
|
||||
bf.WriteUint16(uint16(len(m.Message) + 1))
|
||||
bf.WriteNullTerminatedBytes([]byte(m.Message))
|
||||
bf.WriteNullTerminatedBytes([]byte(m.SenderName))
|
||||
|
||||
return nil
|
||||
}
|
||||
29
Erupe/network/binpacket/msg_bin_mail_notify.go
Normal file
29
Erupe/network/binpacket/msg_bin_mail_notify.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package binpacket
|
||||
|
||||
import (
|
||||
"github.com/Solenataris/Erupe/common/stringsupport"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
type MsgBinMailNotify struct {
|
||||
SenderName string
|
||||
}
|
||||
|
||||
func (m MsgBinMailNotify) Parse(bf *byteframe.ByteFrame) error {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (m MsgBinMailNotify) Build(bf *byteframe.ByteFrame) error {
|
||||
bf.WriteUint8(0x01) // Unk
|
||||
byteName, _ := stringsupport.ConvertUTF8ToShiftJIS(m.SenderName)
|
||||
|
||||
bf.WriteBytes(byteName)
|
||||
bf.WriteBytes(make([]byte, 21-len(byteName)))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m MsgBinMailNotify) Opcode() network.PacketID {
|
||||
return network.MSG_SYS_CASTED_BINARY
|
||||
}
|
||||
46
Erupe/network/binpacket/msg_bin_targeted.go
Normal file
46
Erupe/network/binpacket/msg_bin_targeted.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package binpacket
|
||||
|
||||
import (
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgBinTargeted is a format used for some broadcast types
|
||||
// to target specific players, instead of groups (world, stage, etc).
|
||||
// It forwards a normal binpacket in it's RawDataPayload
|
||||
type MsgBinTargeted struct {
|
||||
TargetCount uint16
|
||||
TargetCharIDs []uint32
|
||||
RawDataPayload []byte // The regular binary payload to be forwarded to the targets.
|
||||
}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgBinTargeted) Opcode() network.PacketID {
|
||||
return network.MSG_SYS_CAST_BINARY
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgBinTargeted) Parse(bf *byteframe.ByteFrame) error {
|
||||
m.TargetCount = bf.ReadUint16()
|
||||
|
||||
m.TargetCharIDs = make([]uint32, m.TargetCount)
|
||||
for i := uint16(0); i < m.TargetCount; i++ {
|
||||
m.TargetCharIDs[i] = bf.ReadUint32()
|
||||
}
|
||||
|
||||
m.RawDataPayload = bf.DataFromCurrent()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgBinTargeted) Build(bf *byteframe.ByteFrame) error {
|
||||
bf.WriteUint16(m.TargetCount)
|
||||
|
||||
for i := 0; i < int(m.TargetCount); i++ {
|
||||
bf.WriteUint32(m.TargetCharIDs[i])
|
||||
}
|
||||
|
||||
bf.WriteBytes(m.RawDataPayload)
|
||||
return nil
|
||||
}
|
||||
8
Erupe/network/clientctx/clientcontext.go
Normal file
8
Erupe/network/clientctx/clientcontext.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package clientctx
|
||||
|
||||
import "github.com/Solenataris/Erupe/common/stringsupport"
|
||||
|
||||
// ClientContext holds contextual data required for packet encoding/decoding.
|
||||
type ClientContext struct {
|
||||
StrConv *stringsupport.StringConverter
|
||||
}
|
||||
125
Erupe/network/crypt_conn.go
Normal file
125
Erupe/network/crypt_conn.go
Normal file
@@ -0,0 +1,125 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/crypto"
|
||||
)
|
||||
|
||||
// CryptConn represents a MHF encrypted two-way connection,
|
||||
// it automatically handles encryption, decryption, and key rotation via it's methods.
|
||||
type CryptConn struct {
|
||||
conn net.Conn
|
||||
readKeyRot uint32
|
||||
sendKeyRot uint32
|
||||
sentPackets int32
|
||||
prevRecvPacketCombinedCheck uint16
|
||||
prevSendPacketCombinedCheck uint16
|
||||
}
|
||||
|
||||
// NewCryptConn creates a new CryptConn with proper default values.
|
||||
func NewCryptConn(conn net.Conn) *CryptConn {
|
||||
cc := &CryptConn{
|
||||
conn: conn,
|
||||
readKeyRot: 995117,
|
||||
sendKeyRot: 995117,
|
||||
}
|
||||
return cc
|
||||
}
|
||||
|
||||
// ReadPacket reads an packet from the connection and returns the decrypted data.
|
||||
func (cc *CryptConn) ReadPacket() ([]byte, error) {
|
||||
|
||||
// Read the raw 14 byte header.
|
||||
headerData := make([]byte, CryptPacketHeaderLength)
|
||||
_, err := io.ReadFull(cc.conn, headerData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Parse the data into a usable struct.
|
||||
cph, err := NewCryptPacketHeader(headerData)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Now read the encrypted packet body after getting its size from the header.
|
||||
encryptedPacketBody := make([]byte, cph.DataSize)
|
||||
_, err = io.ReadFull(cc.conn, encryptedPacketBody)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Update the key rotation before decrypting.
|
||||
if cph.KeyRotDelta != 0 {
|
||||
cc.readKeyRot = (uint32(cph.KeyRotDelta) * (cc.readKeyRot + 1))
|
||||
}
|
||||
|
||||
out, combinedCheck, check0, check1, check2 := crypto.Decrypt(encryptedPacketBody, cc.readKeyRot, nil)
|
||||
if cph.Check0 != check0 || cph.Check1 != check1 || cph.Check2 != check2 {
|
||||
fmt.Printf("got c0 %X, c1 %X, c2 %X\n", check0, check1, check2)
|
||||
fmt.Printf("want c0 %X, c1 %X, c2 %X\n", cph.Check0, cph.Check1, cph.Check2)
|
||||
fmt.Printf("headerData:\n%s\n", hex.Dump(headerData))
|
||||
fmt.Printf("encryptedPacketBody:\n%s\n", hex.Dump(encryptedPacketBody))
|
||||
|
||||
// Attempt to bruteforce it.
|
||||
fmt.Println("Crypto out of sync? Attempting bruteforce")
|
||||
for key := byte(0); key < 255; key++ {
|
||||
out, combinedCheck, check0, check1, check2 = crypto.Decrypt(encryptedPacketBody, 0, &key)
|
||||
//fmt.Printf("Key: 0x%X\n%s\n", key, hex.Dump(out))
|
||||
if cph.Check0 == check0 && cph.Check1 == check1 && cph.Check2 == check2 {
|
||||
fmt.Printf("Bruceforce successful, override key: 0x%X\n", key)
|
||||
|
||||
// Try to fix key for subsequent packets?
|
||||
//cc.readKeyRot = (uint32(key) << 1) + 999983
|
||||
|
||||
cc.prevRecvPacketCombinedCheck = combinedCheck
|
||||
return out, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, errors.New("decrypted data checksum doesn't match header")
|
||||
}
|
||||
|
||||
cc.prevRecvPacketCombinedCheck = combinedCheck
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// SendPacket encrypts and sends a packet.
|
||||
func (cc *CryptConn) SendPacket(data []byte) error {
|
||||
keyRotDelta := byte(3)
|
||||
|
||||
if keyRotDelta != 0 {
|
||||
cc.sendKeyRot = (uint32(keyRotDelta) * (cc.sendKeyRot + 1))
|
||||
}
|
||||
|
||||
// Encrypt the data
|
||||
encData, combinedCheck, check0, check1, check2 := crypto.Encrypt(data, cc.sendKeyRot, nil)
|
||||
|
||||
header := &CryptPacketHeader{}
|
||||
header.Pf0 = byte(((uint(len(encData)) >> 12) & 0xF3) | 3)
|
||||
header.KeyRotDelta = keyRotDelta
|
||||
header.PacketNum = uint16(cc.sentPackets)
|
||||
header.DataSize = uint16(len(encData))
|
||||
header.PrevPacketCombinedCheck = cc.prevSendPacketCombinedCheck
|
||||
header.Check0 = check0
|
||||
header.Check1 = check1
|
||||
header.Check2 = check2
|
||||
|
||||
headerBytes, err := header.Encode()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cc.conn.Write(headerBytes)
|
||||
cc.conn.Write(encData)
|
||||
|
||||
cc.sentPackets++
|
||||
cc.prevSendPacketCombinedCheck = combinedCheck
|
||||
|
||||
return nil
|
||||
}
|
||||
90
Erupe/network/crypt_packet.go
Normal file
90
Erupe/network/crypt_packet.go
Normal file
@@ -0,0 +1,90 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
)
|
||||
|
||||
const (
|
||||
// CryptPacketHeaderLength represents the byte-length of
|
||||
// an encrypted packet header.
|
||||
CryptPacketHeaderLength = 14
|
||||
)
|
||||
|
||||
// CryptPacketHeader represents the parsed information of an encrypted packet header.
|
||||
type CryptPacketHeader struct {
|
||||
Pf0 byte
|
||||
KeyRotDelta byte
|
||||
PacketNum uint16
|
||||
DataSize uint16
|
||||
PrevPacketCombinedCheck uint16
|
||||
Check0 uint16
|
||||
Check1 uint16
|
||||
Check2 uint16
|
||||
}
|
||||
|
||||
// NewCryptPacketHeader parses raw bytes into a CryptPacketHeader
|
||||
func NewCryptPacketHeader(data []byte) (*CryptPacketHeader, error) {
|
||||
var c = CryptPacketHeader{}
|
||||
|
||||
r := bytes.NewReader(data)
|
||||
|
||||
var err error
|
||||
err = binary.Read(r, binary.BigEndian, &c.Pf0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = binary.Read(r, binary.BigEndian, &c.KeyRotDelta)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = binary.Read(r, binary.BigEndian, &c.PacketNum)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = binary.Read(r, binary.BigEndian, &c.DataSize)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = binary.Read(r, binary.BigEndian, &c.PrevPacketCombinedCheck)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = binary.Read(r, binary.BigEndian, &c.Check0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = binary.Read(r, binary.BigEndian, &c.Check1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = binary.Read(r, binary.BigEndian, &c.Check2)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &c, nil
|
||||
}
|
||||
|
||||
// Encode encodes the CryptPacketHeader into raw bytes.
|
||||
func (c *CryptPacketHeader) Encode() ([]byte, error) {
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
var data = []interface{}{
|
||||
c.Pf0,
|
||||
c.KeyRotDelta,
|
||||
c.PacketNum,
|
||||
c.DataSize,
|
||||
c.PrevPacketCombinedCheck,
|
||||
c.Check0,
|
||||
c.Check1,
|
||||
c.Check2,
|
||||
}
|
||||
for _, v := range data {
|
||||
err := binary.Write(buf, binary.BigEndian, v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
84
Erupe/network/crypto/crypto.go
Normal file
84
Erupe/network/crypto/crypto.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package crypto
|
||||
|
||||
var (
|
||||
_encryptKey = []byte{0x90, 0x51, 0x26, 0x25, 0x04, 0xBF, 0xCF, 0x4C, 0x92, 0x02, 0x52, 0x7A, 0x70, 0x1A, 0x41, 0x88, 0x8C, 0xC2, 0xCE, 0xB8, 0xF6, 0x57, 0x7E, 0xBA, 0x83, 0x63, 0x2C, 0x24, 0x9A, 0x67, 0x86, 0x0C, 0xBE, 0x72, 0xFD, 0xB6, 0x7B, 0x79, 0xB0, 0x22, 0x5A, 0x60, 0x5C, 0x4F, 0x49, 0xE2, 0x0E, 0xF5, 0x3A, 0x81, 0xAE, 0x11, 0x6B, 0xF0, 0xA1, 0x01, 0xE8, 0x65, 0x8D, 0x5B, 0xDC, 0xCC, 0x93, 0x18, 0xB3, 0xAB, 0x77, 0xF7, 0x8E, 0xEC, 0xEF, 0x05, 0x00, 0xCA, 0x4E, 0xA7, 0xBC, 0xB5, 0x10, 0xC6, 0x6C, 0xC0, 0xC4, 0xE5, 0x87, 0x3F, 0xC1, 0x82, 0x29, 0x96, 0x45, 0x73, 0x07, 0xCB, 0x43, 0xF9, 0xF3, 0x08, 0x89, 0xD0, 0x99, 0x6A, 0x3B, 0x37, 0x19, 0xD4, 0x40, 0xEA, 0xD7, 0x85, 0x16, 0x66, 0x1E, 0x9C, 0x39, 0xBB, 0xEE, 0x4A, 0x03, 0x8A, 0x36, 0x2D, 0x13, 0x1D, 0x56, 0x48, 0xC7, 0x0D, 0x59, 0xB2, 0x44, 0xA3, 0xFE, 0x8B, 0x32, 0x1B, 0x84, 0xA0, 0x2E, 0x62, 0x17, 0x42, 0xB9, 0x9B, 0x2B, 0x75, 0xD8, 0x1C, 0x3C, 0x4D, 0x76, 0x27, 0x6E, 0x28, 0xD3, 0x33, 0xC3, 0x21, 0xAF, 0x34, 0x23, 0xDD, 0x68, 0x9F, 0xF1, 0xAD, 0xE1, 0xB4, 0xE7, 0xA6, 0x74, 0x15, 0x4B, 0xFA, 0x3D, 0x5F, 0x7C, 0xDA, 0x2F, 0x0A, 0xE3, 0x7D, 0xC8, 0xB7, 0x12, 0x6F, 0x9E, 0xA9, 0x14, 0x53, 0x97, 0x8F, 0x64, 0xF4, 0xF8, 0xA2, 0xA4, 0x2A, 0xD2, 0x47, 0x9D, 0x71, 0xC5, 0xE9, 0x06, 0x98, 0x20, 0x54, 0x80, 0xAA, 0xF2, 0xAC, 0x50, 0xD6, 0x7F, 0xD9, 0xC9, 0xCD, 0x69, 0x46, 0x6D, 0x30, 0xB1, 0x58, 0x0B, 0x55, 0xD1, 0x5D, 0xD5, 0xBD, 0x31, 0xDE, 0xA5, 0xE4, 0x91, 0x0F, 0x61, 0x38, 0xDF, 0xA8, 0xE6, 0x3E, 0x1F, 0x35, 0xED, 0xDB, 0x94, 0xEB, 0x09, 0x5E, 0x95, 0xFB, 0xFC, 0xE0, 0x78, 0xFF}
|
||||
_decryptKey = []byte{0x48, 0x37, 0x09, 0x76, 0x04, 0x47, 0xCC, 0x5C, 0x61, 0xF8, 0xB3, 0xE0, 0x1F, 0x7F, 0x2E, 0xEB, 0x4E, 0x33, 0xB8, 0x7A, 0xBC, 0xAB, 0x6E, 0x8C, 0x3F, 0x68, 0x0D, 0x87, 0x93, 0x7B, 0x70, 0xF2, 0xCE, 0x9D, 0x27, 0xA0, 0x1B, 0x03, 0x02, 0x97, 0x99, 0x58, 0xC5, 0x90, 0x1A, 0x79, 0x8A, 0xB2, 0xDD, 0xE6, 0x86, 0x9B, 0x9F, 0xF3, 0x78, 0x67, 0xED, 0x72, 0x30, 0x66, 0x94, 0xAE, 0xF1, 0x55, 0x6A, 0x0E, 0x8D, 0x5E, 0x82, 0x5A, 0xDB, 0xC7, 0x7D, 0x2C, 0x75, 0xAC, 0x07, 0x95, 0x4A, 0x2B, 0xD4, 0x01, 0x0A, 0xBD, 0xCF, 0xE1, 0x7C, 0x15, 0xDF, 0x80, 0x28, 0x3B, 0x2A, 0xE3, 0xF9, 0xAF, 0x29, 0xEC, 0x8B, 0x19, 0xC0, 0x39, 0x6F, 0x1D, 0xA2, 0xDA, 0x65, 0x34, 0x50, 0xDC, 0x98, 0xB9, 0x0C, 0xC9, 0x21, 0x5B, 0xAA, 0x91, 0x96, 0x42, 0xFE, 0x25, 0x0B, 0x24, 0xB0, 0xB5, 0x16, 0xD6, 0xD0, 0x31, 0x57, 0x18, 0x88, 0x6D, 0x1E, 0x54, 0x0F, 0x62, 0x77, 0x85, 0x10, 0x3A, 0x44, 0xBF, 0x00, 0xEA, 0x08, 0x3E, 0xF6, 0xFA, 0x59, 0xBE, 0xCD, 0x64, 0x1C, 0x8F, 0x71, 0xC8, 0xBA, 0xA3, 0x89, 0x36, 0xC3, 0x83, 0xC4, 0xE8, 0xA9, 0x4B, 0xEF, 0xBB, 0xD1, 0x41, 0xD3, 0xA5, 0x32, 0x9E, 0x26, 0xDE, 0x81, 0x40, 0xA7, 0x4D, 0x23, 0xB7, 0x13, 0x8E, 0x17, 0x73, 0x4C, 0xE5, 0x20, 0x05, 0x51, 0x56, 0x11, 0x9C, 0x52, 0xCA, 0x4F, 0x7E, 0xB6, 0xD8, 0x49, 0x5D, 0x3D, 0xD9, 0x12, 0x06, 0x63, 0xE2, 0xC6, 0x9A, 0x69, 0xE4, 0xD5, 0x6C, 0x92, 0xD7, 0xB1, 0xF5, 0x3C, 0xA1, 0xE7, 0xEE, 0xFD, 0xA6, 0x2D, 0xB4, 0xE9, 0x53, 0xF0, 0xA8, 0x38, 0xCB, 0x6B, 0xF7, 0x45, 0xF4, 0x74, 0x46, 0x35, 0xA4, 0xD2, 0x60, 0xC1, 0x2F, 0x14, 0x43, 0xC2, 0x5F, 0xAD, 0xFB, 0xFC, 0x22, 0x84, 0xFF}
|
||||
_sharedCryptKey = []byte{0xDD, 0xA8, 0x5F, 0x1E, 0x57, 0xAF, 0xC0, 0xCC, 0x43, 0x35, 0x8F, 0xBB, 0x6F, 0xE6, 0xA1, 0xD6, 0x60, 0xB9, 0x1A, 0xAE, 0x20, 0x49, 0x24, 0x81, 0x21, 0xFE, 0x86, 0x2B, 0x98, 0xB7, 0xB3, 0xD2, 0x91, 0x01, 0x3A, 0x4C, 0x65, 0x92, 0x1C, 0xF4, 0xBE, 0xDD, 0xD9, 0x08, 0xE6, 0x81, 0x98, 0x1B, 0x8D, 0x60, 0xF3, 0x6F, 0xA1, 0x47, 0x24, 0xF1, 0x53, 0x45, 0xC8, 0x7B, 0x88, 0x80, 0x4E, 0x36, 0xC3, 0x0D, 0xC9, 0xD6, 0x8B, 0x08, 0x19, 0x0B, 0xA5, 0xC1, 0x11, 0x4C, 0x60, 0xF8, 0x5D, 0xFC, 0x15, 0x68, 0x7E, 0x32, 0xC0, 0x50, 0xAB, 0x64, 0x1F, 0x8A, 0xD4, 0x08, 0x39, 0x7F, 0xC2, 0xFB, 0xBA, 0x6C, 0xF0, 0xE6, 0xB0, 0x31, 0x10, 0xC1, 0xBF, 0x75, 0x43, 0xBB, 0x18, 0x04, 0x0D, 0xD1, 0x97, 0xF7, 0x23, 0x21, 0x83, 0x8B, 0xCA, 0x25, 0x2B, 0xA3, 0x03, 0x13, 0xEA, 0xAE, 0xFE, 0xF0, 0xEB, 0xFD, 0x85, 0x57, 0x53, 0x65, 0x41, 0x2A, 0x40, 0x99, 0xC0, 0x94, 0x65, 0x7E, 0x7C, 0x93, 0x82, 0xB0, 0xB3, 0xE5, 0xC0, 0x21, 0x09, 0x84, 0xD5, 0xEF, 0x9F, 0xD1, 0x7E, 0xDC, 0x4D, 0xF5, 0x7E, 0xCD, 0x45, 0x3C, 0x7F, 0xF5, 0x59, 0x98, 0xC6, 0x55, 0xFC, 0x9F, 0xA3, 0xB7, 0x74, 0xEE, 0x31, 0x98, 0xE6, 0xB7, 0xBE, 0x26, 0xF4, 0x3C, 0x76, 0xF1, 0x23, 0x7E, 0x02, 0x4E, 0x3C, 0xD1, 0xC7, 0x28, 0x23, 0x73, 0xC4, 0xD9, 0x5E, 0x0D, 0xA1, 0x80, 0xA5, 0xAA, 0x26, 0x0A, 0xA3, 0x44, 0x82, 0x74, 0xE6, 0x3C, 0x44, 0x27, 0x51, 0x0D, 0x5F, 0xC7, 0x9C, 0xD6, 0x63, 0x67, 0xA5, 0x27, 0x97, 0x38, 0xFB, 0x2D, 0xD3, 0xD6, 0x60, 0x25, 0x83, 0x4D, 0x37, 0x5B, 0x40, 0x59, 0x11, 0x77, 0x51, 0x11, 0x14, 0x18, 0x07, 0x63, 0xB1, 0x34, 0x3D, 0xB8, 0x60, 0x13, 0xC2, 0xE8, 0x13, 0x82}
|
||||
)
|
||||
|
||||
// Encrypt encrypts the given data using MHF's custom encryption+checksum method.
|
||||
// if a overrideByteKey value is supplied (!= nil), it will be used to override the derived/truncated key byte.
|
||||
func Encrypt(data []byte, key uint32, overrideByteKey *byte) (outputData []byte, combinedCheck uint16, check0 uint16, check1 uint16, check2 uint16) {
|
||||
return _generalCrypt(data, key, 0, overrideByteKey)
|
||||
}
|
||||
|
||||
// Decrypt decrypts the given data using MHF's custom decryption+checksum method.
|
||||
// if a overrideByteKey value is supplied (!= nil), it will be used to override the derived/truncated key byte.
|
||||
func Decrypt(data []byte, key uint32, overrideByteKey *byte) (outputData []byte, combinedCheck uint16, check0 uint16, check1 uint16, check2 uint16) {
|
||||
return _generalCrypt(data, key, 1, overrideByteKey)
|
||||
}
|
||||
|
||||
// _generalCrypt is a generalized MHF crypto function that can perform both encryption and decryption,
|
||||
// these two crypto operations are combined into a single function because they shared most of their logic.
|
||||
// encrypt: cryptType==0
|
||||
// decrypt: cryptType==1
|
||||
func _generalCrypt(data []byte, rotKey uint32, cryptType int, overrideByteKey *byte) ([]byte, uint16, uint16, uint16, uint16) {
|
||||
cryptKeyTruncByte := byte(((rotKey >> 1) % 999983) & 0xFF)
|
||||
if overrideByteKey != nil {
|
||||
cryptKeyTruncByte = *overrideByteKey
|
||||
}
|
||||
|
||||
derivedCryptKey := int32((uint32(len(data)) * (uint32(cryptKeyTruncByte) + 1)) & 0xFFFFFFFF)
|
||||
sharedBufIdx := byte(1)
|
||||
accumulator0 := uint32(0)
|
||||
accumulator1 := uint32(0)
|
||||
accumulator2 := uint32(0)
|
||||
|
||||
var outputData []byte
|
||||
if cryptType == 0 {
|
||||
for i := 0; i < len(data); i++ {
|
||||
// Do the encryption for this iteration
|
||||
encKeyIdx := int32(((uint32(derivedCryptKey) >> 10) ^ uint32(data[i])) & 0xFF)
|
||||
derivedCryptKey = (0x4FD * (derivedCryptKey + 1))
|
||||
encKeyByte := _encryptKey[encKeyIdx]
|
||||
|
||||
// Update the checksum accumulators.
|
||||
accumulator2 = uint32((accumulator2 + (uint32(sharedBufIdx) * uint32(data[i]))) & 0xFFFFFFFF)
|
||||
accumulator1 = uint32((accumulator1 + uint32(encKeyIdx)) & 0xFFFFFFFF)
|
||||
accumulator0 = uint32((accumulator0 + (uint32(encKeyByte)<<(i&7))&0xFFFFFFFF) & 0xFFFFFFFF)
|
||||
|
||||
// Append the output.
|
||||
outputData = append(outputData, _sharedCryptKey[sharedBufIdx]^encKeyByte)
|
||||
|
||||
// Update the sharedBufIdx for the next iteration.
|
||||
sharedBufIdx = data[i]
|
||||
}
|
||||
|
||||
} else if cryptType == 1 {
|
||||
for i := 0; i < len(data); i++ {
|
||||
// Do the decryption for this iteration
|
||||
oldSharedBufIdx := sharedBufIdx
|
||||
tIdx := data[i] ^ _sharedCryptKey[sharedBufIdx]
|
||||
decKeyByte := _decryptKey[tIdx]
|
||||
sharedBufIdx = byte(((uint32(derivedCryptKey) >> 10) ^ uint32(decKeyByte)) & 0xFF)
|
||||
|
||||
// Update the checksum accumulators.
|
||||
accumulator0 = (accumulator0 + ((uint32(tIdx) << (i & 7)) & 0xFFFFFFFF))
|
||||
accumulator1 = (accumulator1 + uint32(decKeyByte)) & 0xFFFFFFFF
|
||||
accumulator2 = (accumulator2 + ((uint32(oldSharedBufIdx) * uint32(sharedBufIdx)) & 0xFFFFFFFF)) & 0xFFFFFFFF
|
||||
|
||||
// Append the output.
|
||||
outputData = append(outputData, sharedBufIdx)
|
||||
|
||||
// Update the key pos for next iteration.
|
||||
derivedCryptKey = (0x4FD * (derivedCryptKey + 1))
|
||||
}
|
||||
}
|
||||
|
||||
combinedCheck := uint16((accumulator1 + (accumulator0 >> 1) + (accumulator2 >> 2)) & 0xFFFF)
|
||||
check0 := uint16((accumulator0 ^ ((accumulator0 & 0xFFFF0000) >> 16)) & 0xFFFF)
|
||||
check1 := uint16((accumulator1 ^ ((accumulator1 & 0xFFFF0000) >> 16)) & 0xFFFF)
|
||||
check2 := uint16((accumulator2 ^ ((accumulator2 & 0xFFFF0000) >> 16)) & 0xFFFF)
|
||||
|
||||
return outputData, combinedCheck, check0, check1, check2
|
||||
}
|
||||
104
Erupe/network/crypto/crypto_test.go
Normal file
104
Erupe/network/crypto/crypto_test.go
Normal file
@@ -0,0 +1,104 @@
|
||||
package crypto
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var commonTestData = []byte{0x74, 0x65, 0x73, 0x74}
|
||||
var tests = []struct {
|
||||
decryptedData []byte
|
||||
key uint32
|
||||
encryptedData []byte
|
||||
ecc, ec0, ec1, ec2 uint16
|
||||
}{
|
||||
{
|
||||
commonTestData,
|
||||
0,
|
||||
[]byte{0x46, 0x53, 0x28, 0x5E},
|
||||
0x2976, 0x06ea, 0x0215, 0x08FB3,
|
||||
},
|
||||
{
|
||||
commonTestData,
|
||||
3,
|
||||
[]byte{0x46, 0x95, 0x88, 0xEA},
|
||||
0x2AE4, 0x0A56, 0x01CD, 0x08FB3,
|
||||
},
|
||||
/*
|
||||
// TODO(Andoryuuta): This case fails. Debug the client and figure out if this is valid expected data.
|
||||
{
|
||||
commonTestData,
|
||||
995117,
|
||||
[]byte{0x46, 0x28, 0xFF, 0xAA},
|
||||
0x2A22, 0x09D4, 0x014C, 0x08FB3,
|
||||
},
|
||||
*/
|
||||
{
|
||||
commonTestData,
|
||||
0x7FFFFFFF,
|
||||
[]byte{0x46, 0x53, 0x28, 0x5E},
|
||||
0x2976, 0x06ea, 0x0215, 0x08FB3,
|
||||
},
|
||||
{
|
||||
commonTestData,
|
||||
0x80000000,
|
||||
[]byte{0x46, 0x95, 0x88, 0xEA},
|
||||
0x2AE4, 0x0A56, 0x01CD, 0x08FB3,
|
||||
},
|
||||
{
|
||||
commonTestData,
|
||||
0xFFFFFFFF,
|
||||
[]byte{0x46, 0xB5, 0xDC, 0xB2},
|
||||
0x2ADD, 0x09A6, 0x021E, 0x08FB3,
|
||||
},
|
||||
{
|
||||
[]byte{0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x12, 0x00, 0xDE, 0x00, 0x03, 0x00, 0x00, 0x00, 0x30, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x20, 0x18, 0x46, 0x00, 0x00, 0x80, 0x3F, 0xDC, 0xE4, 0x0A, 0x46, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x67, 0xD3, 0x5B, 0x00, 0x77, 0x01, 0x78, 0x00, 0x77, 0x01, 0x4F, 0x01, 0x5B, 0x6F, 0x76, 0xC5, 0x30, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xDD, 0x17, 0x46, 0x00, 0x00, 0x80, 0x3F, 0x9E, 0x11, 0x0C, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x37, 0x64, 0x00, 0x2C, 0x01, 0x64, 0x00, 0x2C, 0x01, 0x4F, 0x01, 0x5B, 0x6F, 0x76, 0xC5, 0x00, 0x10},
|
||||
2000476,
|
||||
[]byte{0x2E, 0x52, 0x24, 0xE3, 0x05, 0x2B, 0xFC, 0x04, 0x0B, 0x26, 0x90, 0xEA, 0x61, 0xDB, 0x8D, 0x27, 0xCB, 0xB1, 0x69, 0xA1, 0x77, 0x80, 0x4A, 0xC2, 0xA0, 0xBD, 0x50, 0x54, 0xF5, 0xC2, 0x94, 0x66, 0xBB, 0xCE, 0x53, 0x29, 0xEE, 0xB4, 0xFA, 0xF6, 0x5F, 0x8D, 0x80, 0x3E, 0x5D, 0x5F, 0xB0, 0x53, 0xE6, 0x92, 0x17, 0x80, 0xE7, 0xED, 0xE7, 0xDC, 0x61, 0xF0, 0xCD, 0xE4, 0x41, 0x82, 0x21, 0xBA, 0x47, 0xAB, 0x58, 0xFF, 0x30, 0x76, 0x80, 0x2D, 0x38, 0xF4, 0xDF, 0x86, 0x8C, 0x6C, 0x8D, 0x33, 0x4C, 0x37, 0xA3, 0xDA, 0x01, 0x3C, 0x98, 0x66, 0x1F, 0xB9, 0xE2, 0xEA, 0xF0, 0x84, 0xE8, 0xAA, 0x00, 0x3D, 0x4A, 0xB6, 0xF2, 0x3D, 0x91, 0x58, 0x4B, 0x0B, 0xE2, 0xD5, 0xC7, 0x39, 0x4D, 0x59, 0xED, 0xC3, 0x61, 0x6F, 0x6E, 0x69, 0x9B, 0x3C},
|
||||
0xCFF8, 0x086B, 0x3BAE, 0x4057,
|
||||
},
|
||||
}
|
||||
|
||||
func TestEncrypt(t *testing.T) {
|
||||
for k, tt := range tests {
|
||||
testname := fmt.Sprintf("encrypt_test_%d", k)
|
||||
t.Run(testname, func(t *testing.T) {
|
||||
out, cc, c0, c1, c2 := Encrypt(tt.decryptedData, tt.key, nil)
|
||||
if cc != tt.ecc {
|
||||
t.Errorf("got cc 0x%X, want 0x%X", cc, tt.ecc)
|
||||
} else if c0 != tt.ec0 {
|
||||
t.Errorf("got c0 0x%X, want 0x%X", c0, tt.ec0)
|
||||
} else if c1 != tt.ec1 {
|
||||
t.Errorf("got c1 0x%X, want 0x%X", c1, tt.ec1)
|
||||
} else if c2 != tt.ec2 {
|
||||
t.Errorf("got c2 0x%X, want 0x%X", c2, tt.ec2)
|
||||
} else if !bytes.Equal(out, tt.encryptedData) {
|
||||
t.Errorf("got out\n\t%s\nwant\n\t%s", hex.Dump(out), hex.Dump(tt.encryptedData))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestDecrypt(t *testing.T) {
|
||||
for k, tt := range tests {
|
||||
testname := fmt.Sprintf("decrypt_test_%d", k)
|
||||
t.Run(testname, func(t *testing.T) {
|
||||
out, cc, c0, c1, c2 := Decrypt(tt.encryptedData, tt.key, nil)
|
||||
if cc != tt.ecc {
|
||||
t.Errorf("got cc 0x%X, want 0x%X", cc, tt.ecc)
|
||||
} else if c0 != tt.ec0 {
|
||||
t.Errorf("got c0 0x%X, want 0x%X", c0, tt.ec0)
|
||||
} else if c1 != tt.ec1 {
|
||||
t.Errorf("got c1 0x%X, want 0x%X", c1, tt.ec1)
|
||||
} else if c2 != tt.ec2 {
|
||||
t.Errorf("got c2 0x%X, want 0x%X", c2, tt.ec2)
|
||||
} else if !bytes.Equal(out, tt.decryptedData) {
|
||||
t.Errorf("got out\n\t%s\nwant\n\t%s", hex.Dump(out), hex.Dump(tt.decryptedData))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
29
Erupe/network/mhfpacket/mhfpacket.go
Normal file
29
Erupe/network/mhfpacket/mhfpacket.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
)
|
||||
|
||||
// Parser is the interface that wraps the Parse method.
|
||||
type Parser interface {
|
||||
Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error
|
||||
}
|
||||
|
||||
// Builder is the interface that wraps the Build method.
|
||||
type Builder interface {
|
||||
Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error
|
||||
}
|
||||
|
||||
// Opcoder is the interface that wraps the Opcode method.
|
||||
type Opcoder interface {
|
||||
Opcode() network.PacketID
|
||||
}
|
||||
|
||||
// MHFPacket is the interface that groups the Parse, Build, and Opcode methods.
|
||||
type MHFPacket interface {
|
||||
Parser
|
||||
Builder
|
||||
Opcoder
|
||||
}
|
||||
27
Erupe/network/mhfpacket/msg_ca_exchange_item.go
Normal file
27
Erupe/network/mhfpacket/msg_ca_exchange_item.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
)
|
||||
|
||||
// MsgCaExchangeItem represents the MSG_CA_EXCHANGE_ITEM
|
||||
type MsgCaExchangeItem struct{}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgCaExchangeItem) Opcode() network.PacketID {
|
||||
return network.MSG_CA_EXCHANGE_ITEM
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgCaExchangeItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgCaExchangeItem) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
28
Erupe/network/mhfpacket/msg_head.go
Normal file
28
Erupe/network/mhfpacket/msg_head.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgHead represents the MSG_HEAD
|
||||
type MsgHead struct{}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgHead) Opcode() network.PacketID {
|
||||
return network.MSG_HEAD
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgHead) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgHead) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
28
Erupe/network/mhfpacket/msg_mhf_accept_read_reward.go
Normal file
28
Erupe/network/mhfpacket/msg_mhf_accept_read_reward.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAcceptReadReward represents the MSG_MHF_ACCEPT_READ_REWARD
|
||||
type MsgMhfAcceptReadReward struct{}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAcceptReadReward) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ACCEPT_READ_REWARD
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAcceptReadReward) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAcceptReadReward) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
41
Erupe/network/mhfpacket/msg_mhf_acquire_cafe_item.go
Normal file
41
Erupe/network/mhfpacket/msg_mhf_acquire_cafe_item.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAcquireCafeItem represents the MSG_MHF_ACQUIRE_CAFE_ITEM
|
||||
type MsgMhfAcquireCafeItem struct {
|
||||
AckHandle uint32
|
||||
// Valid sizes, not sure if [un]signed.
|
||||
ItemType uint16
|
||||
ItemID uint16
|
||||
Quant uint16
|
||||
PointCost uint32
|
||||
Unk0 uint16
|
||||
}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAcquireCafeItem) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ACQUIRE_CAFE_ITEM
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAcquireCafeItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
m.AckHandle = bf.ReadUint32()
|
||||
m.ItemType = bf.ReadUint16()
|
||||
m.ItemID = bf.ReadUint16()
|
||||
m.Quant = bf.ReadUint16()
|
||||
m.PointCost = bf.ReadUint32()
|
||||
m.Unk0 = bf.ReadUint16()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAcquireCafeItem) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
35
Erupe/network/mhfpacket/msg_mhf_acquire_dist_item.go
Normal file
35
Erupe/network/mhfpacket/msg_mhf_acquire_dist_item.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAcquireDistItem represents the MSG_MHF_ACQUIRE_DIST_ITEM
|
||||
type MsgMhfAcquireDistItem struct {
|
||||
AckHandle uint32
|
||||
// Valid field size(s), not sure about the types.
|
||||
Unk0 uint8
|
||||
Unk1 uint32
|
||||
}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAcquireDistItem) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ACQUIRE_DIST_ITEM
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAcquireDistItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
m.AckHandle = bf.ReadUint32()
|
||||
m.Unk0 = bf.ReadUint8()
|
||||
m.Unk1 = bf.ReadUint32()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAcquireDistItem) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
35
Erupe/network/mhfpacket/msg_mhf_acquire_exchange_shop.go
Normal file
35
Erupe/network/mhfpacket/msg_mhf_acquire_exchange_shop.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAcquireExchangeShop represents the MSG_MHF_ACQUIRE_EXCHANGE_SHOP
|
||||
type MsgMhfAcquireExchangeShop struct {
|
||||
AckHandle uint32
|
||||
DataSize uint16
|
||||
RawDataPayload []byte
|
||||
}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAcquireExchangeShop) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ACQUIRE_EXCHANGE_SHOP
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAcquireExchangeShop) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
m.AckHandle = bf.ReadUint32()
|
||||
m.DataSize = bf.ReadUint16()
|
||||
m.RawDataPayload = bf.ReadBytes(uint(m.DataSize))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAcquireExchangeShop) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
bf.WriteUint32(m.AckHandle)
|
||||
bf.WriteUint16(m.DataSize)
|
||||
bf.WriteBytes(m.RawDataPayload)
|
||||
return nil
|
||||
}
|
||||
27
Erupe/network/mhfpacket/msg_mhf_acquire_festa.go
Normal file
27
Erupe/network/mhfpacket/msg_mhf_acquire_festa.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAcquireFesta represents the MSG_MHF_ACQUIRE_FESTA
|
||||
type MsgMhfAcquireFesta struct{}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAcquireFesta) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ACQUIRE_FESTA
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAcquireFesta) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAcquireFesta) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAcquireFestaIntermediatePrize represents the MSG_MHF_ACQUIRE_FESTA_INTERMEDIATE_PRIZE
|
||||
type MsgMhfAcquireFestaIntermediatePrize struct{}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAcquireFestaIntermediatePrize) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ACQUIRE_FESTA_INTERMEDIATE_PRIZE
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAcquireFestaIntermediatePrize) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAcquireFestaIntermediatePrize) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAcquireFestaPersonalPrize represents the MSG_MHF_ACQUIRE_FESTA_PERSONAL_PRIZE
|
||||
type MsgMhfAcquireFestaPersonalPrize struct{}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAcquireFestaPersonalPrize) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ACQUIRE_FESTA_PERSONAL_PRIZE
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAcquireFestaPersonalPrize) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAcquireFestaPersonalPrize) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
27
Erupe/network/mhfpacket/msg_mhf_acquire_guild_adventure.go
Normal file
27
Erupe/network/mhfpacket/msg_mhf_acquire_guild_adventure.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAcquireGuildAdventure represents the MSG_MHF_ACQUIRE_GUILD_ADVENTURE
|
||||
type MsgMhfAcquireGuildAdventure struct{}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAcquireGuildAdventure) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ACQUIRE_GUILD_ADVENTURE
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAcquireGuildAdventure) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAcquireGuildAdventure) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
27
Erupe/network/mhfpacket/msg_mhf_acquire_guild_tresure.go
Normal file
27
Erupe/network/mhfpacket/msg_mhf_acquire_guild_tresure.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAcquireGuildTresure represents the MSG_MHF_ACQUIRE_GUILD_TRESURE
|
||||
type MsgMhfAcquireGuildTresure struct{}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAcquireGuildTresure) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ACQUIRE_GUILD_TRESURE
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAcquireGuildTresure) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAcquireGuildTresure) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAcquireGuildTresureSouvenir represents the MSG_MHF_ACQUIRE_GUILD_TRESURE_SOUVENIR
|
||||
type MsgMhfAcquireGuildTresureSouvenir struct {
|
||||
AckHandle uint32
|
||||
}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAcquireGuildTresureSouvenir) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ACQUIRE_GUILD_TRESURE_SOUVENIR
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAcquireGuildTresureSouvenir) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
m.AckHandle = bf.ReadUint32()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAcquireGuildTresureSouvenir) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
27
Erupe/network/mhfpacket/msg_mhf_acquire_item.go
Normal file
27
Erupe/network/mhfpacket/msg_mhf_acquire_item.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAcquireItem represents the MSG_MHF_ACQUIRE_ITEM
|
||||
type MsgMhfAcquireItem struct{}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAcquireItem) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ACQUIRE_ITEM
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAcquireItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAcquireItem) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
27
Erupe/network/mhfpacket/msg_mhf_acquire_monthly_item.go
Normal file
27
Erupe/network/mhfpacket/msg_mhf_acquire_monthly_item.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAcquireMonthlyItem represents the MSG_MHF_ACQUIRE_MONTHLY_ITEM
|
||||
type MsgMhfAcquireMonthlyItem struct{}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAcquireMonthlyItem) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ACQUIRE_MONTHLY_ITEM
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAcquireMonthlyItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAcquireMonthlyItem) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
30
Erupe/network/mhfpacket/msg_mhf_acquire_monthly_reward.go
Normal file
30
Erupe/network/mhfpacket/msg_mhf_acquire_monthly_reward.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAcquireMonthlyReward represents the MSG_MHF_ACQUIRE_MONTHLY_REWARD
|
||||
type MsgMhfAcquireMonthlyReward struct {
|
||||
AckHandle uint32
|
||||
}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAcquireMonthlyReward) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ACQUIRE_MONTHLY_REWARD
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAcquireMonthlyReward) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
m.AckHandle = bf.ReadUint32()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAcquireMonthlyReward) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
27
Erupe/network/mhfpacket/msg_mhf_acquire_title.go
Normal file
27
Erupe/network/mhfpacket/msg_mhf_acquire_title.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAcquireTitle represents the MSG_MHF_ACQUIRE_TITLE
|
||||
type MsgMhfAcquireTitle struct{}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAcquireTitle) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ACQUIRE_TITLE
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAcquireTitle) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAcquireTitle) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
27
Erupe/network/mhfpacket/msg_mhf_acquire_tournament.go
Normal file
27
Erupe/network/mhfpacket/msg_mhf_acquire_tournament.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAcquireTournament represents the MSG_MHF_ACQUIRE_TOURNAMENT
|
||||
type MsgMhfAcquireTournament struct{}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAcquireTournament) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ACQUIRE_TOURNAMENT
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAcquireTournament) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAcquireTournament) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
27
Erupe/network/mhfpacket/msg_mhf_acquire_ud_item.go
Normal file
27
Erupe/network/mhfpacket/msg_mhf_acquire_ud_item.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAcquireUdItem represents the MSG_MHF_ACQUIRE_UD_ITEM
|
||||
type MsgMhfAcquireUdItem struct{}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAcquireUdItem) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ACQUIRE_UD_ITEM
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAcquireUdItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAcquireUdItem) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
36
Erupe/network/mhfpacket/msg_mhf_add_achievement.go
Normal file
36
Erupe/network/mhfpacket/msg_mhf_add_achievement.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAddAchievement represents the MSG_MHF_ADD_ACHIEVEMENT
|
||||
type MsgMhfAddAchievement struct {
|
||||
Unk0 uint8
|
||||
Unk1 uint16
|
||||
Unk2 uint16
|
||||
}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAddAchievement) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ADD_ACHIEVEMENT
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAddAchievement) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
m.Unk0 = bf.ReadUint8()
|
||||
m.Unk1 = bf.ReadUint16()
|
||||
m.Unk2 = bf.ReadUint16()
|
||||
// doesn't expect a response
|
||||
return nil
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAddAchievement) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
bf.WriteUint8(m.Unk0)
|
||||
bf.WriteUint16(m.Unk1)
|
||||
bf.WriteUint16(m.Unk2)
|
||||
return nil
|
||||
}
|
||||
27
Erupe/network/mhfpacket/msg_mhf_add_guild_mission_count.go
Normal file
27
Erupe/network/mhfpacket/msg_mhf_add_guild_mission_count.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAddGuildMissionCount represents the MSG_MHF_ADD_GUILD_MISSION_COUNT
|
||||
type MsgMhfAddGuildMissionCount struct{}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAddGuildMissionCount) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ADD_GUILD_MISSION_COUNT
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAddGuildMissionCount) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAddGuildMissionCount) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAddGuildWeeklyBonusExceptionalUser represents the MSG_MHF_ADD_GUILD_WEEKLY_BONUS_EXCEPTIONAL_USER
|
||||
type MsgMhfAddGuildWeeklyBonusExceptionalUser struct{}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAddGuildWeeklyBonusExceptionalUser) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ADD_GUILD_WEEKLY_BONUS_EXCEPTIONAL_USER
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAddGuildWeeklyBonusExceptionalUser) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAddGuildWeeklyBonusExceptionalUser) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
32
Erupe/network/mhfpacket/msg_mhf_add_kouryou_point.go
Normal file
32
Erupe/network/mhfpacket/msg_mhf_add_kouryou_point.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAddKouryouPoint represents the MSG_MHF_ADD_KOURYOU_POINT
|
||||
type MsgMhfAddKouryouPoint struct {
|
||||
AckHandle uint32
|
||||
KouryouPoints uint32
|
||||
}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAddKouryouPoint) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ADD_KOURYOU_POINT
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAddKouryouPoint) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
m.AckHandle = bf.ReadUint32()
|
||||
m.KouryouPoints = bf.ReadUint32()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAddKouryouPoint) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
bf.WriteUint32(m.AckHandle)
|
||||
bf.WriteUint32(m.KouryouPoints)
|
||||
return nil
|
||||
}
|
||||
27
Erupe/network/mhfpacket/msg_mhf_add_reward_song_count.go
Normal file
27
Erupe/network/mhfpacket/msg_mhf_add_reward_song_count.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAddRewardSongCount represents the MSG_MHF_ADD_REWARD_SONG_COUNT
|
||||
type MsgMhfAddRewardSongCount struct{}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAddRewardSongCount) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ADD_REWARD_SONG_COUNT
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAddRewardSongCount) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAddRewardSongCount) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
36
Erupe/network/mhfpacket/msg_mhf_add_ud_point.go
Normal file
36
Erupe/network/mhfpacket/msg_mhf_add_ud_point.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAddUdPoint represents the MSG_MHF_ADD_UD_POINT
|
||||
type MsgMhfAddUdPoint struct {
|
||||
AckHandle uint32
|
||||
Unk1 uint32
|
||||
Unk2 uint32
|
||||
}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAddUdPoint) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ADD_UD_POINT
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAddUdPoint) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
m.AckHandle = bf.ReadUint32()
|
||||
m.Unk1 = bf.ReadUint32()
|
||||
m.Unk2 = bf.ReadUint32()
|
||||
|
||||
return nil
|
||||
//panic("Not implemented")
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAddUdPoint) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
35
Erupe/network/mhfpacket/msg_mhf_add_ud_tactics_point.go
Normal file
35
Erupe/network/mhfpacket/msg_mhf_add_ud_tactics_point.go
Normal file
@@ -0,0 +1,35 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAddUdTacticsPoint represents the MSG_MHF_ADD_UD_TACTICS_POINT
|
||||
type MsgMhfAddUdTacticsPoint struct {
|
||||
AckHandle uint32
|
||||
Unk0 uint16
|
||||
Unk1 uint32
|
||||
}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAddUdTacticsPoint) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ADD_UD_TACTICS_POINT
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAddUdTacticsPoint) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
m.AckHandle = bf.ReadUint32()
|
||||
m.Unk0 = bf.ReadUint16()
|
||||
m.Unk1 = bf.ReadUint32()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAddUdTacticsPoint) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
bf.WriteUint32(m.AckHandle)
|
||||
bf.WriteUint16(m.Unk0)
|
||||
bf.WriteUint32(m.Unk1)
|
||||
return nil
|
||||
}
|
||||
27
Erupe/network/mhfpacket/msg_mhf_announce.go
Normal file
27
Erupe/network/mhfpacket/msg_mhf_announce.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAnnounce represents the MSG_MHF_ANNOUNCE
|
||||
type MsgMhfAnnounce struct{}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAnnounce) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ANNOUNCE
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAnnounce) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAnnounce) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
34
Erupe/network/mhfpacket/msg_mhf_answer_guild_scout.go
Normal file
34
Erupe/network/mhfpacket/msg_mhf_answer_guild_scout.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfAnswerGuildScout represents the MSG_MHF_ANSWER_GUILD_SCOUT
|
||||
type MsgMhfAnswerGuildScout struct {
|
||||
AckHandle uint32
|
||||
LeaderID uint32
|
||||
Answer bool
|
||||
}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfAnswerGuildScout) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ANSWER_GUILD_SCOUT
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfAnswerGuildScout) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
m.AckHandle = bf.ReadUint32()
|
||||
m.LeaderID = bf.ReadUint32()
|
||||
m.Answer = bf.ReadBool()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfAnswerGuildScout) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
27
Erupe/network/mhfpacket/msg_mhf_apply_bbs_article.go
Normal file
27
Erupe/network/mhfpacket/msg_mhf_apply_bbs_article.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfApplyBbsArticle represents the MSG_MHF_APPLY_BBS_ARTICLE
|
||||
type MsgMhfApplyBbsArticle struct{}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfApplyBbsArticle) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_APPLY_BBS_ARTICLE
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfApplyBbsArticle) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfApplyBbsArticle) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
38
Erupe/network/mhfpacket/msg_mhf_apply_campaign.go
Normal file
38
Erupe/network/mhfpacket/msg_mhf_apply_campaign.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfApplyCampaign represents the MSG_MHF_APPLY_CAMPAIGN
|
||||
type MsgMhfApplyCampaign struct {
|
||||
AckHandle uint32
|
||||
Unk0 uint8
|
||||
Unk1 uint8
|
||||
Unk2 uint16
|
||||
}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfApplyCampaign) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_APPLY_CAMPAIGN
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfApplyCampaign) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
m.AckHandle = bf.ReadUint32()
|
||||
m.Unk0 = bf.ReadUint8()
|
||||
m.Unk1 = bf.ReadUint8()
|
||||
m.Unk2 = bf.ReadUint16()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfApplyCampaign) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
bf.WriteUint32(m.AckHandle)
|
||||
bf.WriteUint8(m.Unk0)
|
||||
bf.WriteUint8(m.Unk1)
|
||||
bf.WriteUint16(m.Unk2)
|
||||
return nil
|
||||
}
|
||||
41
Erupe/network/mhfpacket/msg_mhf_apply_dist_item.go
Normal file
41
Erupe/network/mhfpacket/msg_mhf_apply_dist_item.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfApplyDistItem represents the MSG_MHF_APPLY_DIST_ITEM
|
||||
type MsgMhfApplyDistItem struct {
|
||||
AckHandle uint32
|
||||
Unk0 uint8
|
||||
RequestType uint32
|
||||
Unk2 uint32
|
||||
Unk3 uint32
|
||||
}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfApplyDistItem) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_APPLY_DIST_ITEM
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfApplyDistItem) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
m.AckHandle = bf.ReadUint32()
|
||||
m.Unk0 = bf.ReadUint8()
|
||||
m.RequestType = bf.ReadUint32()
|
||||
m.Unk2 = bf.ReadUint32()
|
||||
m.Unk3 = bf.ReadUint32()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfApplyDistItem) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
bf.WriteUint32(m.AckHandle)
|
||||
bf.WriteUint8(m.Unk0)
|
||||
bf.WriteUint32(m.RequestType)
|
||||
bf.WriteUint32(m.Unk2)
|
||||
bf.WriteUint32(m.Unk3)
|
||||
return nil
|
||||
}
|
||||
47
Erupe/network/mhfpacket/msg_mhf_arrange_guild_member.go
Normal file
47
Erupe/network/mhfpacket/msg_mhf_arrange_guild_member.go
Normal file
@@ -0,0 +1,47 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfArrangeGuildMember represents the MSG_MHF_ARRANGE_GUILD_MEMBER
|
||||
type MsgMhfArrangeGuildMember struct {
|
||||
AckHandle uint32
|
||||
GuildID uint32
|
||||
CharIDs []uint32
|
||||
}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfArrangeGuildMember) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_ARRANGE_GUILD_MEMBER
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfArrangeGuildMember) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
m.AckHandle = bf.ReadUint32()
|
||||
m.GuildID = bf.ReadUint32()
|
||||
charCount := bf.ReadUint16()
|
||||
|
||||
m.CharIDs = make([]uint32, charCount)
|
||||
|
||||
for i := uint16(0); i < charCount; i++ {
|
||||
m.CharIDs[i] = bf.ReadUint32()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfArrangeGuildMember) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
bf.WriteUint32(m.AckHandle)
|
||||
bf.WriteUint32(m.GuildID)
|
||||
bf.WriteUint16(uint16(len(m.CharIDs)))
|
||||
|
||||
for _, charID := range m.CharIDs {
|
||||
bf.WriteUint32(charID)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfCancelGuildMissionTarget represents the MSG_MHF_CANCEL_GUILD_MISSION_TARGET
|
||||
type MsgMhfCancelGuildMissionTarget struct{}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfCancelGuildMissionTarget) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_CANCEL_GUILD_MISSION_TARGET
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfCancelGuildMissionTarget) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfCancelGuildMissionTarget) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
32
Erupe/network/mhfpacket/msg_mhf_cancel_guild_scout.go
Normal file
32
Erupe/network/mhfpacket/msg_mhf_cancel_guild_scout.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfCancelGuildScout represents the MSG_MHF_CANCEL_GUILD_SCOUT
|
||||
type MsgMhfCancelGuildScout struct {
|
||||
AckHandle uint32
|
||||
InvitationID uint32
|
||||
}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfCancelGuildScout) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_CANCEL_GUILD_SCOUT
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfCancelGuildScout) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
m.AckHandle = bf.ReadUint32()
|
||||
m.InvitationID = bf.ReadUint32()
|
||||
return nil
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfCancelGuildScout) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
27
Erupe/network/mhfpacket/msg_mhf_caravan_my_rank.go
Normal file
27
Erupe/network/mhfpacket/msg_mhf_caravan_my_rank.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfCaravanMyRank represents the MSG_MHF_CARAVAN_MY_RANK
|
||||
type MsgMhfCaravanMyRank struct{}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfCaravanMyRank) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_CARAVAN_MY_RANK
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfCaravanMyRank) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfCaravanMyRank) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
27
Erupe/network/mhfpacket/msg_mhf_caravan_my_score.go
Normal file
27
Erupe/network/mhfpacket/msg_mhf_caravan_my_score.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfCaravanMyScore represents the MSG_MHF_CARAVAN_MY_SCORE
|
||||
type MsgMhfCaravanMyScore struct{}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfCaravanMyScore) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_CARAVAN_MY_SCORE
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfCaravanMyScore) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfCaravanMyScore) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
27
Erupe/network/mhfpacket/msg_mhf_caravan_ranking.go
Normal file
27
Erupe/network/mhfpacket/msg_mhf_caravan_ranking.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package mhfpacket
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/Solenataris/Erupe/network/clientctx"
|
||||
"github.com/Solenataris/Erupe/network"
|
||||
"github.com/Andoryuuta/byteframe"
|
||||
)
|
||||
|
||||
// MsgMhfCaravanRanking represents the MSG_MHF_CARAVAN_RANKING
|
||||
type MsgMhfCaravanRanking struct{}
|
||||
|
||||
// Opcode returns the ID associated with this packet type.
|
||||
func (m *MsgMhfCaravanRanking) Opcode() network.PacketID {
|
||||
return network.MSG_MHF_CARAVAN_RANKING
|
||||
}
|
||||
|
||||
// Parse parses the packet from binary
|
||||
func (m *MsgMhfCaravanRanking) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
|
||||
// Build builds a binary packet from the current data.
|
||||
func (m *MsgMhfCaravanRanking) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||
return errors.New("NOT IMPLEMENTED")
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user