mezfes patch

This commit is contained in:
wishu
2022-07-06 00:19:15 +10:00
parent 307de99281
commit 56e1ac61fe
5 changed files with 193 additions and 278 deletions

View File

@@ -13,7 +13,6 @@
"Enabled": true, "Enabled": true,
"OutputDir": "savedata" "OutputDir": "savedata"
} }
}, },
"discord": { "discord": {
"enabled": false, "enabled": false,
@@ -37,119 +36,69 @@
"sign": { "sign": {
"port": 53312 "port": 53312
}, },
"channel": {
"port1": 54001,
"port2": 54002,
"port3": 54003,
"port4": 54004
},
"entrance": { "entrance": {
"port": 53310, "port": 53310,
"entries": [ "entries": [
{ {
"name": " Server #1", "name": "ANewbie",
"ip": "", "ip": "",
"unk2": 0,
"type": 3, "type": 3,
"recommended": 1,
"season": 3, "season": 3,
"unk6": 0, "allowedclientflags": 4096,
"allowedclientflags": "4096",
"channels": [ "channels": [
{ { "port": 54001, "MaxPlayers": 50, "Unk0": 319, "Unk1": 252, "Unk2": 248 }
"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": "ANormal",
"name": " Server #2",
"ip": "", "ip": "",
"unk2": 0,
"type": 1, "type": 1,
"recommended": 0,
"season": 3, "season": 3,
"unk6": 0,
"allowedclientflags": 0, "allowedclientflags": 0,
"channels": [ "channels": [
{ { "port": 54002, "MaxPlayers": 50, "Unk0": 319, "Unk1": 252, "Unk2": 248 }
"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": "ACities",
"name": " Server #3",
"ip": "", "ip": "",
"unk2": 0,
"type": 2, "type": 2,
"season": 1, "recommended": 1,
"unk6": 0, "season": 3,
"allowedclientflags": 0, "allowedclientflags": 0,
"channels": [ "channels": [
{ { "port": 54003, "MaxPlayers": 50, "Unk0": 319, "Unk1": 252, "Unk2": 248 }
"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": "ATavern",
"name": " Server #4",
"ip": "", "ip": "",
"unk2": 0,
"type": 4, "type": 4,
"season": 0, "recommended": 1,
"unk6": 0, "season": 3,
"allowedclientflags": 0, "allowedclientflags": 0,
"channels": [ "channels": [
{ { "port": 54004, "MaxPlayers": 50, "Unk0": 319, "Unk1": 252, "Unk2": 248 }
"port": 54004, ]
"MaxPlayers": 50, }, {
"CurrentPlayers": 0, "name": "AReturn",
"Unk4": 0, "ip": "",
"Unk5": 0, "type": 5,
"Unk6": 0, "recommended": 1,
"Unk7": 0, "season": 3,
"Unk8": 0, "allowedclientflags": 0,
"Unk9": 0, "channels": [
"Unk10": 318, { "port": 54005, "MaxPlayers": 50, "Unk0": 319, "Unk1": 252, "Unk2": 248 }
"Unk11": 251, ]
"Unk12": 155, }, {
"Unk13": 12345 "name": "AMezFes",
} "ip": "",
"type": 6,
"recommended": 1,
"season": 3,
"allowedclientflags": 0,
"channels": [
{ "port": 54006, "MaxPlayers": 50, "Unk0": 319, "Unk1": 252, "Unk2": 248 }
] ]
} }
] ]
} }

View File

@@ -18,7 +18,6 @@ type Config struct {
Database Database Database Database
Launcher Launcher Launcher Launcher
Sign Sign Sign Sign
Channel Channel
Entrance Entrance Entrance Entrance
} }
@@ -69,14 +68,6 @@ type Sign struct {
Port int 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. // Entrance holds the entrance server config.
type Entrance struct { type Entrance struct {
Port uint16 Port uint16
@@ -86,10 +77,9 @@ type Entrance struct {
// EntranceServerInfo represents an entry in the serverlist. // EntranceServerInfo represents an entry in the serverlist.
type EntranceServerInfo struct { type EntranceServerInfo struct {
IP string IP string
Unk2 uint16
Type uint8 // Server type. 0=?, 1=open, 2=cities, 3=newbie, 4=bar Type uint8 // Server type. 0=?, 1=open, 2=cities, 3=newbie, 4=bar
Season uint8 // Server activity. 0 = green, 1 = orange, 2 = blue Season uint8 // Server activity. 0 = green, 1 = orange, 2 = blue
Unk6 uint8 // Something to do with server recommendation on 0, 3, and 5. Recommended 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). Name string // Server name, 66 byte null terminated Shift-JIS(JP) or Big5(TW).
// 4096(PC, PS3/PS4)?, 8258(PC, PS3/PS4)?, 8192 == nothing? // 4096(PC, PS3/PS4)?, 8258(PC, PS3/PS4)?, 8192 == nothing?
@@ -104,16 +94,9 @@ type EntranceChannelInfo struct {
Port uint16 Port uint16
MaxPlayers uint16 MaxPlayers uint16
CurrentPlayers uint16 CurrentPlayers uint16
Unk4 uint16 Unk0 uint16
Unk5 uint16 Unk1 uint16
Unk6 uint16 Unk2 uint16
Unk7 uint16
Unk8 uint16
Unk9 uint16
Unk10 uint16
Unk11 uint16
Unk12 uint16
Unk13 uint16
} }
// getOutboundIP4 gets the preferred outbound ip4 of this machine // getOutboundIP4 gets the preferred outbound ip4 of this machine

View File

@@ -108,7 +108,7 @@ func main() {
if err != nil { if err != nil {
logger.Fatal("Failed to start launcher server", zap.Error(err)) logger.Fatal("Failed to start launcher server", zap.Error(err))
} }
logger.Info("Started launcher server.") logger.Info("Started launcher server")
// Entrance server. // Entrance server.
entranceServer := entranceserver.NewServer( entranceServer := entranceserver.NewServer(
@@ -121,7 +121,7 @@ func main() {
if err != nil { if err != nil {
logger.Fatal("Failed to start entrance server", zap.Error(err)) logger.Fatal("Failed to start entrance server", zap.Error(err))
} }
logger.Info("Started entrance server.") logger.Info("Started entrance server")
// Sign server. // Sign server.
signServer := signserver.NewServer( signServer := signserver.NewServer(
@@ -134,79 +134,39 @@ func main() {
if err != nil { if err != nil {
logger.Fatal("Failed to start sign server", zap.Error(err)) logger.Fatal("Failed to start sign server", zap.Error(err))
} }
logger.Info("Started sign server.") logger.Info("Started sign server")
// Channel Server var channels []channelserver.Server
channelServer1 := channelserver.NewServer( count := 1
&channelserver.Config{ for _, ee := range erupeConfig.Entrance.Entries {
Logger: logger.Named("channel"), for _, ce := range ee.Channels {
c := *channelserver.NewServer(&channelserver.Config{
Logger: logger.Named("channel-"+fmt.Sprint(count)),
ErupeConfig: erupeConfig, ErupeConfig: erupeConfig,
DB: db, DB: db,
Name: erupeConfig.Entrance.Entries[0].Name,
Enable: erupeConfig.Entrance.Entries[0].Channels[0].MaxPlayers > 0,
//DiscordBot: discordBot,
})
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,
Name: erupeConfig.Entrance.Entries[1].Name,
Enable: erupeConfig.Entrance.Entries[1].Channels[0].MaxPlayers > 0,
DiscordBot: discordBot, DiscordBot: discordBot,
}) })
err = c.Start(int(ce.Port))
err = channelServer2.Start(erupeConfig.Channel.Port2)
if err != nil { if err != nil {
logger.Fatal("Failed to start channel server2", zap.Error(err)) logger.Fatal("Failed to start channel", zap.Error(err))
} else {
logger.Info(fmt.Sprintf("Started channel server %d on port %d", count, ce.Port))
}
channels = append(channels, c)
count++
}
} }
// Channel Server
channelServer3 := channelserver.NewServer(
&channelserver.Config{
Logger: logger.Named("channel"),
ErupeConfig: erupeConfig,
DB: db,
Name: erupeConfig.Entrance.Entries[2].Name,
Enable: erupeConfig.Entrance.Entries[2].Channels[0].MaxPlayers > 0,
//DiscordBot: discordBot,
})
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,
Name: erupeConfig.Entrance.Entries[3].Name,
Enable: erupeConfig.Entrance.Entries[3].Channels[0].MaxPlayers > 0,
//DiscordBot: discordBot,
})
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. // Wait for exit or interrupt with ctrl+C.
c := make(chan os.Signal, 1) c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, syscall.SIGTERM) signal.Notify(c, os.Interrupt, syscall.SIGTERM)
<-c <-c
logger.Info("Trying to shutdown gracefully.") logger.Info("Trying to shutdown gracefully")
channelServer4.Shutdown()
channelServer3.Shutdown() for _, c := range channels {
channelServer2.Shutdown() c.Shutdown()
channelServer1.Shutdown() }
signServer.Shutdown() signServer.Shutdown()
entranceServer.Shutdown() entranceServer.Shutdown()
launcherServer.Shutdown() launcherServer.Shutdown()

View File

@@ -45,11 +45,11 @@ func encodeServerInfo(serverInfos []config.EntranceServerInfo, s *Server) []byte
} }
bf.WriteUint32(binary.LittleEndian.Uint32(net.ParseIP(si.IP).To4())) bf.WriteUint32(binary.LittleEndian.Uint32(net.ParseIP(si.IP).To4()))
bf.WriteUint16(16 + uint16(serverIdx)) bf.WriteUint16(16 + uint16(serverIdx))
bf.WriteUint16(si.Unk2) bf.WriteUint16(0x0000)
bf.WriteUint16(uint16(len(si.Channels))) bf.WriteUint16(uint16(len(si.Channels)))
bf.WriteUint8(si.Type) bf.WriteUint8(si.Type)
bf.WriteUint8(season) bf.WriteUint8(season)
bf.WriteUint8(si.Unk6) bf.WriteUint8(si.Recommended)
shiftjisName, err := stringsupport.ConvertUTF8ToShiftJIS(si.Name) shiftjisName, err := stringsupport.ConvertUTF8ToShiftJIS(si.Name)
if err != nil { if err != nil {
panic(err) panic(err)
@@ -66,16 +66,13 @@ func encodeServerInfo(serverInfos []config.EntranceServerInfo, s *Server) []byte
panic(err) panic(err)
} }
bf.WriteUint16(currentplayers) bf.WriteUint16(currentplayers)
bf.WriteUint16(ci.Unk4) bf.WriteUint32(0)
bf.WriteUint16(ci.Unk5) bf.WriteUint32(0)
bf.WriteUint16(ci.Unk6) bf.WriteUint32(0)
bf.WriteUint16(ci.Unk7) bf.WriteUint16(ci.Unk0)
bf.WriteUint16(ci.Unk8) bf.WriteUint16(ci.Unk1)
bf.WriteUint16(ci.Unk9) bf.WriteUint16(ci.Unk2)
bf.WriteUint16(ci.Unk10) bf.WriteUint16(0x3039)
bf.WriteUint16(ci.Unk11)
bf.WriteUint16(ci.Unk12)
bf.WriteUint16(ci.Unk13)
} }
} }
bf.WriteUint32(uint32(channelserver.Time_Current_Adjusted().Unix())) bf.WriteUint32(uint32(channelserver.Time_Current_Adjusted().Unix()))

View File

@@ -4,6 +4,10 @@ import (
"fmt" "fmt"
"math/rand" "math/rand"
"time" "time"
"encoding/hex"
"io/ioutil"
"path/filepath"
"erupe-ce/server/channelserver"
"github.com/Andoryuuta/byteframe" "github.com/Andoryuuta/byteframe"
"go.uber.org/zap" "go.uber.org/zap"
@@ -56,22 +60,20 @@ func (s *Session) makeSignInResp(uid int) []byte {
token := randSeq(16) token := randSeq(16)
// TODO: register token to db, users table // TODO: register token to db, users table
t := japanese.ShiftJIS.NewEncoder()
bf := byteframe.NewByteFrame() bf := byteframe.NewByteFrame()
bf.WriteUint8(1) // resp_code bf.WriteUint8(1) // resp_code
bf.WriteUint8(0) // file/patch server count bf.WriteUint8(0) // file/patch server count
bf.WriteUint8(4) // entrance server count bf.WriteUint8(1) // entrance server count
bf.WriteUint8(uint8(len(chars))) // character count bf.WriteUint8(uint8(len(chars))) // character count
bf.WriteUint32(0xFFFFFFFF) // login_token_number bf.WriteUint32(0xFFFFFFFF) // login_token_number
bf.WriteBytes(paddedString(token, 16)) // login_token (16 byte padded string) bf.WriteBytes(paddedString(token, 16)) // login_token (16 byte padded string)
bf.WriteUint32(1576761190) bf.WriteUint32(uint32(time.Now().Unix())) // unk timestamp
uint8PascalString(bf, fmt.Sprintf("%s:%d", s.server.erupeConfig.HostIP, s.server.erupeConfig.Entrance.Port)) uint8PascalString(bf, fmt.Sprintf("%s:%d", s.server.erupeConfig.HostIP, s.server.erupeConfig.Entrance.Port))
uint8PascalString(bf, "")
uint8PascalString(bf, "")
uint8PascalString(bf, "mhf-n.capcom.com.tw")
for _, char := range chars { for _, char := range chars {
bf.WriteUint32(char.ID) // character ID 469153291 bf.WriteUint32(char.ID)
// Exp, HR[x] is split by 0, 1, 30, 50, 99, 299, 998, 999 // Exp, HR[x] is split by 0, 1, 30, 50, 99, 299, 998, 999
if s.server.erupeConfig.DevMode && s.server.erupeConfig.DevModeOptions.MaxLauncherHR { if s.server.erupeConfig.DevMode && s.server.erupeConfig.DevModeOptions.MaxLauncherHR {
@@ -80,7 +82,6 @@ func (s *Session) makeSignInResp(uid int) []byte {
bf.WriteUint16(char.HRP) bf.WriteUint16(char.HRP)
} }
t := japanese.ShiftJIS.NewEncoder()
str_name, _, err := transform.String(t, char.Name) str_name, _, err := transform.String(t, char.Name)
if err != nil { if err != nil {
str_name = char.Name str_name = char.Name
@@ -101,23 +102,48 @@ func (s *Session) makeSignInResp(uid int) []byte {
bf.WriteUint8(0) // friends_list_count bf.WriteUint8(0) // friends_list_count
bf.WriteUint8(0) // guild_members_count bf.WriteUint8(0) // guild_members_count
bf.WriteUint8(0) // notice_count bf.WriteUint8(0) // notice_count
bf.WriteUint32(0xDEADBEEF) // some_last_played_character_id
// noticeText := "<BODY><CENTER><SIZE_3><C_4>Welcome to Erupe SU9!<BR><BODY><LEFT><SIZE_2><C_5>Erupe is experimental software<C_7>, we are not liable for any<BR><BODY>issues caused by installing the software!<BR><BODY><BR><BODY><C_4>■Report bugs on Discord!<C_7><BR><BODY><BR><BODY><C_4>■Test everything!<C_7><BR><BODY><BR><BODY><C_4>■Don't talk to softlocking NPCs!<C_7><BR><BODY><BR><BODY><C_4>■Fork the code on GitHub!<C_7><BR><BODY><BR><BODY>Thank you to all of the contributors,<BR><BODY><BR><BODY>this wouldn't exist without you."
// notice_transformed, _, err := transform.String(t, noticeText)
// if err != nil {
// panic(err)
// }
// bf.WriteUint32(uint32(len(notice_transformed)+1))
// bf.WriteNullTerminatedBytes([]byte(notice_transformed))
bf.WriteUint32(0) // some_last_played_character_id
bf.WriteUint32(14) // unk_flags bf.WriteUint32(14) // unk_flags
uint8PascalString(bf, "") // unk_data_blob PascalString
bf.WriteUint16(51728) filters, err := ioutil.ReadFile(filepath.Join(s.server.erupeConfig.BinPath, "filters.bin")) //dsmc name and msg obj
bf.WriteUint16(20000) if err != nil {
uint16PascalString(bf, "1000672925") panic(err)
}
bf.WriteBytes(filters)
bf.WriteUint8(0) bf.WriteUint32(0xCA104E20)
uint16PascalString(bf, "")
bf.WriteUint8(0x00)
bf.WriteUint32(0xCA110001)
bf.WriteUint32(0x4E200000)
bf.WriteUint16(51729) returning := false
bf.WriteUint16(1) // return course end time
bf.WriteUint16(20000) if returning {
uint16PascalString(bf, "203.191.249.36:8080") bf.WriteUint32(uint32(channelserver.Time_Current_Adjusted().Add(30 * 24 * time.Hour).Unix()))
} else {
bf.WriteUint32(1578905116)
bf.WriteUint32(0) bf.WriteUint32(0)
}
bf.WriteUint32(0x00000000)
bf.WriteBool(true) // mezfes active
bf.WriteUint16(0x0000)
bf.WriteUint8(0x00)
bf.WriteUint32(uint32(channelserver.Time_Current_Adjusted().Add(-5 * time.Minute).Unix())) // mezfes start time
bf.WriteUint32(uint32(channelserver.Time_Current_Adjusted().Add(24 * time.Hour * 7).Unix())) // mezfes end time
endBytes, _ := hex.DecodeString("020000002700000027080A03060904080507")
bf.WriteBytes(endBytes)
return bf.Data() return bf.Data()
} }