mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-30 12:33:18 +02:00
Merge pull request #72 from ZeruLight/fix/dynamic-tune-vals
dynamic tune values
This commit is contained in:
@@ -2,6 +2,7 @@ package stringsupport
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -96,3 +97,23 @@ func CSVElems(csv string) []int {
|
|||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CSVGetIndex(csv string, i int) int {
|
||||||
|
s := CSVElems(csv)
|
||||||
|
if i < len(s) {
|
||||||
|
return s[i]
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func CSVSetIndex(csv string, i int, v int) string {
|
||||||
|
s := CSVElems(csv)
|
||||||
|
if i < len(s) {
|
||||||
|
s[i] = v
|
||||||
|
}
|
||||||
|
var r []string
|
||||||
|
for j := 0; j < len(s); j++ {
|
||||||
|
r = append(r, fmt.Sprintf(`%d`, s[j]))
|
||||||
|
}
|
||||||
|
return strings.Join(r, ",")
|
||||||
|
}
|
||||||
|
|||||||
16
config.json
16
config.json
@@ -11,6 +11,7 @@
|
|||||||
"PatchServerFile": "",
|
"PatchServerFile": "",
|
||||||
"ScreenshotAPIURL": "",
|
"ScreenshotAPIURL": "",
|
||||||
"DeleteOnSaveCorruption": false,
|
"DeleteOnSaveCorruption": false,
|
||||||
|
"ClientMode": "ZZ",
|
||||||
"DevMode": true,
|
"DevMode": true,
|
||||||
"DevModeOptions": {
|
"DevModeOptions": {
|
||||||
"AutoCreateAccount": true,
|
"AutoCreateAccount": true,
|
||||||
@@ -27,6 +28,8 @@
|
|||||||
"DisableTokenCheck": false,
|
"DisableTokenCheck": false,
|
||||||
"QuestDebugTools": false,
|
"QuestDebugTools": false,
|
||||||
"EarthStatusOverride": 0,
|
"EarthStatusOverride": 0,
|
||||||
|
"EarthIDOverride": 0,
|
||||||
|
"EarthMonsterOverride": 0,
|
||||||
"SaveDumps": {
|
"SaveDumps": {
|
||||||
"Enabled": true,
|
"Enabled": true,
|
||||||
"OutputDir": "savedata"
|
"OutputDir": "savedata"
|
||||||
@@ -43,7 +46,18 @@
|
|||||||
"BonusQuestAllowance": 3,
|
"BonusQuestAllowance": 3,
|
||||||
"DailyQuestAllowance": 1,
|
"DailyQuestAllowance": 1,
|
||||||
"MezfesSoloTickets": 10,
|
"MezfesSoloTickets": 10,
|
||||||
"MezfesGroupTickets": 4
|
"MezfesGroupTickets": 4,
|
||||||
|
"GUrgentRate": 10,
|
||||||
|
"GCPMultiplier": 1.00,
|
||||||
|
"GRPMultiplier": 1.00,
|
||||||
|
"GSRPMultiplier": 1.00,
|
||||||
|
"GZennyMultiplier": 1.00,
|
||||||
|
"MaterialMultiplier": 1.00,
|
||||||
|
"ExtraCarves": 0,
|
||||||
|
"DisableHunterNavi": false,
|
||||||
|
"EnableHiganjimaEvent": false,
|
||||||
|
"EnableNierEvent": false,
|
||||||
|
"DisableRoad": false
|
||||||
},
|
},
|
||||||
"Discord": {
|
"Discord": {
|
||||||
"Enabled": false,
|
"Enabled": false,
|
||||||
|
|||||||
@@ -1,15 +1,28 @@
|
|||||||
package config
|
package _config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Mode string
|
||||||
|
|
||||||
|
const (
|
||||||
|
ZZ Mode = "ZZ"
|
||||||
|
Z2 Mode = "Z2"
|
||||||
|
Z1 Mode = "Z1"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (m Mode) String() string {
|
||||||
|
return string(m)
|
||||||
|
}
|
||||||
|
|
||||||
// Config holds the global server-wide config.
|
// Config holds the global server-wide config.
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Host string `mapstructure:"Host"`
|
Host string `mapstructure:"Host"`
|
||||||
@@ -22,6 +35,7 @@ type Config struct {
|
|||||||
PatchServerFile string // File patch server override
|
PatchServerFile string // File patch server override
|
||||||
ScreenshotAPIURL string // Destination for screenshots uploaded to BBS
|
ScreenshotAPIURL string // Destination for screenshots uploaded to BBS
|
||||||
DeleteOnSaveCorruption bool // Attempts to save corrupted data will flag the save for deletion
|
DeleteOnSaveCorruption bool // Attempts to save corrupted data will flag the save for deletion
|
||||||
|
ClientMode Mode
|
||||||
DevMode bool
|
DevMode bool
|
||||||
|
|
||||||
DevModeOptions DevModeOptions
|
DevModeOptions DevModeOptions
|
||||||
@@ -38,21 +52,23 @@ type Config struct {
|
|||||||
|
|
||||||
// DevModeOptions holds various debug/temporary options for use while developing Erupe.
|
// DevModeOptions holds various debug/temporary options for use while developing Erupe.
|
||||||
type DevModeOptions struct {
|
type DevModeOptions struct {
|
||||||
AutoCreateAccount bool // Automatically create accounts if they don't exist
|
AutoCreateAccount bool // Automatically create accounts if they don't exist
|
||||||
CleanDB bool // Automatically wipes the DB on server reset.
|
CleanDB bool // Automatically wipes the DB on server reset.
|
||||||
MaxLauncherHR bool // Sets the HR returned in the launcher to HR7 so that you can join non-beginner worlds.
|
MaxLauncherHR bool // Sets the HR returned in the launcher to HR7 so that you can join non-beginner worlds.
|
||||||
LogInboundMessages bool // Log all messages sent to the server
|
LogInboundMessages bool // Log all messages sent to the server
|
||||||
LogOutboundMessages bool // Log all messages sent to the clients
|
LogOutboundMessages bool // Log all messages sent to the clients
|
||||||
MaxHexdumpLength int // Maximum number of bytes printed when logs are enabled
|
MaxHexdumpLength int // Maximum number of bytes printed when logs are enabled
|
||||||
DivaEvent int // Diva Defense event status
|
DivaEvent int // Diva Defense event status
|
||||||
FestaEvent int // Hunter's Festa event status
|
FestaEvent int // Hunter's Festa event status
|
||||||
TournamentEvent int // VS Tournament event status
|
TournamentEvent int // VS Tournament event status
|
||||||
MezFesEvent bool // MezFes status
|
MezFesEvent bool // MezFes status
|
||||||
MezFesAlt bool // Swaps out Volpakkun for Tokotoko
|
MezFesAlt bool // Swaps out Volpakkun for Tokotoko
|
||||||
DisableTokenCheck bool // Disables checking login token exists in the DB (security risk!)
|
DisableTokenCheck bool // Disables checking login token exists in the DB (security risk!)
|
||||||
QuestDebugTools bool // Enable various quest debug logs
|
QuestDebugTools bool // Enable various quest debug logs
|
||||||
EarthStatusOverride int32
|
EarthStatusOverride int32
|
||||||
SaveDumps SaveDumpOptions
|
EarthIDOverride int32
|
||||||
|
EarthMonsterOverride int32
|
||||||
|
SaveDumps SaveDumpOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
type SaveDumpOptions struct {
|
type SaveDumpOptions struct {
|
||||||
@@ -62,17 +78,28 @@ type SaveDumpOptions struct {
|
|||||||
|
|
||||||
// GameplayOptions has various gameplay modifiers
|
// GameplayOptions has various gameplay modifiers
|
||||||
type GameplayOptions struct {
|
type GameplayOptions struct {
|
||||||
FeaturedWeapons int // Number of Active Feature weapons to generate daily
|
FeaturedWeapons int // Number of Active Feature weapons to generate daily
|
||||||
MaximumNP int // Maximum number of NP held by a player
|
MaximumNP int // Maximum number of NP held by a player
|
||||||
MaximumRP uint16 // Maximum number of RP held by a player
|
MaximumRP uint16 // Maximum number of RP held by a player
|
||||||
DisableLoginBoost bool // Disables the Login Boost system
|
DisableLoginBoost bool // Disables the Login Boost system
|
||||||
DisableBoostTime bool // Disables the daily NetCafe Boost Time
|
DisableBoostTime bool // Disables the daily NetCafe Boost Time
|
||||||
BoostTimeDuration int // The number of minutes NetCafe Boost Time lasts for
|
BoostTimeDuration int // The number of minutes NetCafe Boost Time lasts for
|
||||||
GuildMealDuration int // The number of minutes a Guild Meal can be activated for after cooking
|
GuildMealDuration int // The number of minutes a Guild Meal can be activated for after cooking
|
||||||
BonusQuestAllowance uint32 // Number of Bonus Point Quests to allow daily
|
BonusQuestAllowance uint32 // Number of Bonus Point Quests to allow daily
|
||||||
DailyQuestAllowance uint32 // Number of Daily Quests to allow daily
|
DailyQuestAllowance uint32 // Number of Daily Quests to allow daily
|
||||||
MezfesSoloTickets uint32 // Number of solo tickets given weekly
|
MezfesSoloTickets uint32 // Number of solo tickets given weekly
|
||||||
MezfesGroupTickets uint32 // Number of group tickets given weekly
|
MezfesGroupTickets uint32 // Number of group tickets given weekly
|
||||||
|
GUrgentRate uint16 // Adjusts the rate of G Urgent quests spawning
|
||||||
|
GCPMultiplier float32 // Adjusts the multiplier of GCP rewarded for quest completion
|
||||||
|
GRPMultiplier float32 // Adjusts the multiplier of G Rank Points rewarded for quest completion
|
||||||
|
GSRPMultiplier float32 // Adjusts the multiplier of G Skill Rank Points rewarded for quest completion
|
||||||
|
GZennyMultiplier float32 // Adjusts the multiplier of G Zenny rewarded for quest completion
|
||||||
|
MaterialMultiplier float32 // Adjusts the multiplier of Monster Materials rewarded for quest completion
|
||||||
|
ExtraCarves uint16 // Grant n extra chances to carve ALL carcasses
|
||||||
|
DisableHunterNavi bool // Disables the Hunter Navi
|
||||||
|
EnableHiganjimaEvent bool // Enables the Higanjima event in the Rasta Bar
|
||||||
|
EnableNierEvent bool // Enables the Nier event in the Rasta Bar
|
||||||
|
DisableRoad bool // Disables the Hunting Road
|
||||||
}
|
}
|
||||||
|
|
||||||
// Discord holds the discord integration config.
|
// Discord holds the discord integration config.
|
||||||
@@ -157,7 +184,6 @@ func init() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
preventClose(fmt.Sprintf("Failed to load config: %s", err.Error()))
|
preventClose(fmt.Sprintf("Failed to load config: %s", err.Error()))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// getOutboundIP4 gets the preferred outbound ip4 of this machine
|
// getOutboundIP4 gets the preferred outbound ip4 of this machine
|
||||||
@@ -199,6 +225,15 @@ func LoadConfig() (*Config, error) {
|
|||||||
c.Host = getOutboundIP4().To4().String()
|
c.Host = getOutboundIP4().To4().String()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch strings.ToUpper(c.ClientMode.String()) {
|
||||||
|
case "Z1":
|
||||||
|
c.ClientMode = Z1
|
||||||
|
case "Z2":
|
||||||
|
c.ClientMode = Z2
|
||||||
|
default:
|
||||||
|
c.ClientMode = ZZ
|
||||||
|
}
|
||||||
|
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
64
main.go
64
main.go
@@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
_config "erupe-ce/config"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
@@ -9,7 +10,6 @@ import (
|
|||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"erupe-ce/config"
|
|
||||||
"erupe-ce/server/channelserver"
|
"erupe-ce/server/channelserver"
|
||||||
"erupe-ce/server/discordbot"
|
"erupe-ce/server/discordbot"
|
||||||
"erupe-ce/server/entranceserver"
|
"erupe-ce/server/entranceserver"
|
||||||
@@ -45,7 +45,8 @@ func main() {
|
|||||||
var err error
|
var err error
|
||||||
|
|
||||||
var zapLogger *zap.Logger
|
var zapLogger *zap.Logger
|
||||||
if config.ErupeConfig.DevMode {
|
config := _config.ErupeConfig
|
||||||
|
if config.DevMode {
|
||||||
zapLogger, _ = zap.NewDevelopment()
|
zapLogger, _ = zap.NewDevelopment()
|
||||||
} else {
|
} else {
|
||||||
zapLogger, _ = zap.NewProduction()
|
zapLogger, _ = zap.NewProduction()
|
||||||
@@ -55,20 +56,21 @@ func main() {
|
|||||||
logger := zapLogger.Named("main")
|
logger := zapLogger.Named("main")
|
||||||
|
|
||||||
logger.Info(fmt.Sprintf("Starting Erupe (9.3b-%s)", Commit()))
|
logger.Info(fmt.Sprintf("Starting Erupe (9.3b-%s)", Commit()))
|
||||||
|
logger.Info(fmt.Sprintf("Client Mode: %s", config.ClientMode.String()))
|
||||||
|
|
||||||
if config.ErupeConfig.Database.Password == "" {
|
if config.Database.Password == "" {
|
||||||
preventClose("Database password is blank")
|
preventClose("Database password is blank")
|
||||||
}
|
}
|
||||||
|
|
||||||
if net.ParseIP(config.ErupeConfig.Host) == nil {
|
if net.ParseIP(config.Host) == nil {
|
||||||
ips, _ := net.LookupIP(config.ErupeConfig.Host)
|
ips, _ := net.LookupIP(config.Host)
|
||||||
for _, ip := range ips {
|
for _, ip := range ips {
|
||||||
if ip != nil {
|
if ip != nil {
|
||||||
config.ErupeConfig.Host = ip.String()
|
config.Host = ip.String()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if net.ParseIP(config.ErupeConfig.Host) == nil {
|
if net.ParseIP(config.Host) == nil {
|
||||||
preventClose("Invalid host address")
|
preventClose("Invalid host address")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,10 +78,10 @@ func main() {
|
|||||||
// Discord bot
|
// Discord bot
|
||||||
var discordBot *discordbot.DiscordBot = nil
|
var discordBot *discordbot.DiscordBot = nil
|
||||||
|
|
||||||
if config.ErupeConfig.Discord.Enabled {
|
if config.Discord.Enabled {
|
||||||
bot, err := discordbot.NewDiscordBot(discordbot.Options{
|
bot, err := discordbot.NewDiscordBot(discordbot.Options{
|
||||||
Logger: logger,
|
Logger: logger,
|
||||||
Config: config.ErupeConfig,
|
Config: _config.ErupeConfig,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -102,11 +104,11 @@ func main() {
|
|||||||
// Create the postgres DB pool.
|
// Create the postgres DB pool.
|
||||||
connectString := fmt.Sprintf(
|
connectString := fmt.Sprintf(
|
||||||
"host='%s' port='%d' user='%s' password='%s' dbname='%s' sslmode=disable",
|
"host='%s' port='%d' user='%s' password='%s' dbname='%s' sslmode=disable",
|
||||||
config.ErupeConfig.Database.Host,
|
config.Database.Host,
|
||||||
config.ErupeConfig.Database.Port,
|
config.Database.Port,
|
||||||
config.ErupeConfig.Database.User,
|
config.Database.User,
|
||||||
config.ErupeConfig.Database.Password,
|
config.Database.Password,
|
||||||
config.ErupeConfig.Database.Database,
|
config.Database.Database,
|
||||||
)
|
)
|
||||||
|
|
||||||
db, err := sqlx.Open("postgres", connectString)
|
db, err := sqlx.Open("postgres", connectString)
|
||||||
@@ -126,7 +128,7 @@ func main() {
|
|||||||
_ = db.MustExec("DELETE FROM servers")
|
_ = db.MustExec("DELETE FROM servers")
|
||||||
|
|
||||||
// Clean the DB if the option is on.
|
// Clean the DB if the option is on.
|
||||||
if config.ErupeConfig.DevMode && config.ErupeConfig.DevModeOptions.CleanDB {
|
if config.DevMode && config.DevModeOptions.CleanDB {
|
||||||
logger.Info("Database: Started clearing...")
|
logger.Info("Database: Started clearing...")
|
||||||
cleanDB(db)
|
cleanDB(db)
|
||||||
logger.Info("Database: Finished clearing")
|
logger.Info("Database: Finished clearing")
|
||||||
@@ -139,11 +141,11 @@ func main() {
|
|||||||
// Entrance server.
|
// Entrance server.
|
||||||
|
|
||||||
var entranceServer *entranceserver.Server
|
var entranceServer *entranceserver.Server
|
||||||
if config.ErupeConfig.Entrance.Enabled {
|
if config.Entrance.Enabled {
|
||||||
entranceServer = entranceserver.NewServer(
|
entranceServer = entranceserver.NewServer(
|
||||||
&entranceserver.Config{
|
&entranceserver.Config{
|
||||||
Logger: logger.Named("entrance"),
|
Logger: logger.Named("entrance"),
|
||||||
ErupeConfig: config.ErupeConfig,
|
ErupeConfig: _config.ErupeConfig,
|
||||||
DB: db,
|
DB: db,
|
||||||
})
|
})
|
||||||
err = entranceServer.Start()
|
err = entranceServer.Start()
|
||||||
@@ -158,11 +160,11 @@ func main() {
|
|||||||
// Sign server.
|
// Sign server.
|
||||||
|
|
||||||
var signServer *signserver.Server
|
var signServer *signserver.Server
|
||||||
if config.ErupeConfig.Sign.Enabled {
|
if config.Sign.Enabled {
|
||||||
signServer = signserver.NewServer(
|
signServer = signserver.NewServer(
|
||||||
&signserver.Config{
|
&signserver.Config{
|
||||||
Logger: logger.Named("sign"),
|
Logger: logger.Named("sign"),
|
||||||
ErupeConfig: config.ErupeConfig,
|
ErupeConfig: _config.ErupeConfig,
|
||||||
DB: db,
|
DB: db,
|
||||||
})
|
})
|
||||||
err = signServer.Start()
|
err = signServer.Start()
|
||||||
@@ -176,11 +178,11 @@ func main() {
|
|||||||
|
|
||||||
// New Sign server
|
// New Sign server
|
||||||
var newSignServer *signv2server.Server
|
var newSignServer *signv2server.Server
|
||||||
if config.ErupeConfig.SignV2.Enabled {
|
if config.SignV2.Enabled {
|
||||||
newSignServer = signv2server.NewServer(
|
newSignServer = signv2server.NewServer(
|
||||||
&signv2server.Config{
|
&signv2server.Config{
|
||||||
Logger: logger.Named("sign"),
|
Logger: logger.Named("sign"),
|
||||||
ErupeConfig: config.ErupeConfig,
|
ErupeConfig: _config.ErupeConfig,
|
||||||
DB: db,
|
DB: db,
|
||||||
})
|
})
|
||||||
err = newSignServer.Start()
|
err = newSignServer.Start()
|
||||||
@@ -194,23 +196,23 @@ func main() {
|
|||||||
|
|
||||||
var channels []*channelserver.Server
|
var channels []*channelserver.Server
|
||||||
|
|
||||||
if config.ErupeConfig.Channel.Enabled {
|
if config.Channel.Enabled {
|
||||||
channelQuery := ""
|
channelQuery := ""
|
||||||
si := 0
|
si := 0
|
||||||
ci := 0
|
ci := 0
|
||||||
count := 1
|
count := 1
|
||||||
for j, ee := range config.ErupeConfig.Entrance.Entries {
|
for j, ee := range config.Entrance.Entries {
|
||||||
for i, ce := range ee.Channels {
|
for i, ce := range ee.Channels {
|
||||||
sid := (4096 + si*256) + (16 + ci)
|
sid := (4096 + si*256) + (16 + ci)
|
||||||
c := *channelserver.NewServer(&channelserver.Config{
|
c := *channelserver.NewServer(&channelserver.Config{
|
||||||
ID: uint16(sid),
|
ID: uint16(sid),
|
||||||
Logger: logger.Named("channel-" + fmt.Sprint(count)),
|
Logger: logger.Named("channel-" + fmt.Sprint(count)),
|
||||||
ErupeConfig: config.ErupeConfig,
|
ErupeConfig: _config.ErupeConfig,
|
||||||
DB: db,
|
DB: db,
|
||||||
DiscordBot: discordBot,
|
DiscordBot: discordBot,
|
||||||
})
|
})
|
||||||
if ee.IP == "" {
|
if ee.IP == "" {
|
||||||
c.IP = config.ErupeConfig.Host
|
c.IP = config.Host
|
||||||
} else {
|
} else {
|
||||||
c.IP = ee.IP
|
c.IP = ee.IP
|
||||||
}
|
}
|
||||||
@@ -246,7 +248,7 @@ func main() {
|
|||||||
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
||||||
<-c
|
<-c
|
||||||
|
|
||||||
if !config.ErupeConfig.DisableSoftCrash {
|
if !config.DisableSoftCrash {
|
||||||
for i := 0; i < 10; i++ {
|
for i := 0; i < 10; i++ {
|
||||||
message := fmt.Sprintf("Shutting down in %d...", 10-i)
|
message := fmt.Sprintf("Shutting down in %d...", 10-i)
|
||||||
for _, c := range channels {
|
for _, c := range channels {
|
||||||
@@ -257,21 +259,21 @@ func main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.ErupeConfig.Channel.Enabled {
|
if config.Channel.Enabled {
|
||||||
for _, c := range channels {
|
for _, c := range channels {
|
||||||
c.Shutdown()
|
c.Shutdown()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.ErupeConfig.Sign.Enabled {
|
if config.Sign.Enabled {
|
||||||
signServer.Shutdown()
|
signServer.Shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.ErupeConfig.SignV2.Enabled {
|
if config.SignV2.Enabled {
|
||||||
newSignServer.Shutdown()
|
newSignServer.Shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.ErupeConfig.Entrance.Enabled {
|
if config.Entrance.Enabled {
|
||||||
entranceServer.Shutdown()
|
entranceServer.Shutdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,7 +287,7 @@ func wait() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func preventClose(text string) {
|
func preventClose(text string) {
|
||||||
if config.ErupeConfig.DisableSoftCrash {
|
if _config.ErupeConfig.DisableSoftCrash {
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
}
|
}
|
||||||
fmt.Println("\nFailed to start Erupe:\n" + text)
|
fmt.Println("\nFailed to start Erupe:\n" + text)
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
package mhfpacket
|
package mhfpacket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfCaravanMyRank represents the MSG_MHF_CARAVAN_MY_RANK
|
// MsgMhfCaravanMyRank represents the MSG_MHF_CARAVAN_MY_RANK
|
||||||
type MsgMhfCaravanMyRank struct{}
|
type MsgMhfCaravanMyRank struct {
|
||||||
|
AckHandle uint32
|
||||||
|
Unk0 uint32
|
||||||
|
Unk1 uint32
|
||||||
|
Unk2 uint32
|
||||||
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
func (m *MsgMhfCaravanMyRank) Opcode() network.PacketID {
|
func (m *MsgMhfCaravanMyRank) Opcode() network.PacketID {
|
||||||
@@ -18,7 +23,11 @@ func (m *MsgMhfCaravanMyRank) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfCaravanMyRank) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfCaravanMyRank) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
return errors.New("NOT IMPLEMENTED")
|
m.AckHandle = bf.ReadUint32()
|
||||||
|
m.Unk0 = bf.ReadUint32()
|
||||||
|
m.Unk1 = bf.ReadUint32()
|
||||||
|
m.Unk2 = bf.ReadUint32()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build builds a binary packet from the current data.
|
// Build builds a binary packet from the current data.
|
||||||
|
|||||||
@@ -1,15 +1,24 @@
|
|||||||
package mhfpacket
|
package mhfpacket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfCaravanMyScore represents the MSG_MHF_CARAVAN_MY_SCORE
|
// MsgMhfCaravanMyScore represents the MSG_MHF_CARAVAN_MY_SCORE
|
||||||
type MsgMhfCaravanMyScore struct{}
|
type MsgMhfCaravanMyScore struct {
|
||||||
|
AckHandle uint32
|
||||||
|
Unk0 uint32
|
||||||
|
Unk1 uint32
|
||||||
|
Unk2 int32
|
||||||
|
Unk3 int32
|
||||||
|
Unk4 uint32
|
||||||
|
Unk5 int32
|
||||||
|
Unk6 int32
|
||||||
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
func (m *MsgMhfCaravanMyScore) Opcode() network.PacketID {
|
func (m *MsgMhfCaravanMyScore) Opcode() network.PacketID {
|
||||||
@@ -18,7 +27,15 @@ func (m *MsgMhfCaravanMyScore) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfCaravanMyScore) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfCaravanMyScore) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
return errors.New("NOT IMPLEMENTED")
|
m.AckHandle = bf.ReadUint32()
|
||||||
|
m.Unk0 = bf.ReadUint32()
|
||||||
|
m.Unk1 = bf.ReadUint32()
|
||||||
|
m.Unk2 = bf.ReadInt32()
|
||||||
|
m.Unk3 = bf.ReadInt32()
|
||||||
|
m.Unk4 = bf.ReadUint32()
|
||||||
|
m.Unk5 = bf.ReadInt32()
|
||||||
|
m.Unk6 = bf.ReadInt32()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build builds a binary packet from the current data.
|
// Build builds a binary packet from the current data.
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
package mhfpacket
|
package mhfpacket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfCaravanRanking represents the MSG_MHF_CARAVAN_RANKING
|
// MsgMhfCaravanRanking represents the MSG_MHF_CARAVAN_RANKING
|
||||||
type MsgMhfCaravanRanking struct{}
|
type MsgMhfCaravanRanking struct {
|
||||||
|
AckHandle uint32
|
||||||
|
Unk0 uint32
|
||||||
|
Unk1 uint32
|
||||||
|
Unk2 int32
|
||||||
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
func (m *MsgMhfCaravanRanking) Opcode() network.PacketID {
|
func (m *MsgMhfCaravanRanking) Opcode() network.PacketID {
|
||||||
@@ -18,7 +23,11 @@ func (m *MsgMhfCaravanRanking) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfCaravanRanking) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfCaravanRanking) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
return errors.New("NOT IMPLEMENTED")
|
m.AckHandle = bf.ReadUint32()
|
||||||
|
m.Unk0 = bf.ReadUint32()
|
||||||
|
m.Unk1 = bf.ReadUint32()
|
||||||
|
m.Unk2 = bf.ReadInt32()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build builds a binary packet from the current data.
|
// Build builds a binary packet from the current data.
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package mhfpacket
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
_config "erupe-ce/config"
|
||||||
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
"erupe-ce/network"
|
"erupe-ce/network"
|
||||||
@@ -30,7 +31,9 @@ func (m *MsgMhfEnumerateQuest) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Cli
|
|||||||
m.World = bf.ReadUint8()
|
m.World = bf.ReadUint8()
|
||||||
m.Counter = bf.ReadUint16()
|
m.Counter = bf.ReadUint16()
|
||||||
m.Offset = bf.ReadUint16()
|
m.Offset = bf.ReadUint16()
|
||||||
m.Unk4 = bf.ReadUint8()
|
if _config.ErupeConfig.ClientMode != _config.Z1 {
|
||||||
|
m.Unk4 = bf.ReadUint8()
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,19 @@
|
|||||||
package mhfpacket
|
package mhfpacket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfGetBreakSeibatuLevelReward represents the MSG_MHF_GET_BREAK_SEIBATU_LEVEL_REWARD
|
// MsgMhfGetBreakSeibatuLevelReward represents the MSG_MHF_GET_BREAK_SEIBATU_LEVEL_REWARD
|
||||||
type MsgMhfGetBreakSeibatuLevelReward struct{}
|
type MsgMhfGetBreakSeibatuLevelReward struct {
|
||||||
|
AckHandle uint32
|
||||||
|
Unk0 uint32
|
||||||
|
Unk1 int32
|
||||||
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
func (m *MsgMhfGetBreakSeibatuLevelReward) Opcode() network.PacketID {
|
func (m *MsgMhfGetBreakSeibatuLevelReward) Opcode() network.PacketID {
|
||||||
@@ -18,7 +22,10 @@ func (m *MsgMhfGetBreakSeibatuLevelReward) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfGetBreakSeibatuLevelReward) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfGetBreakSeibatuLevelReward) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
return errors.New("NOT IMPLEMENTED")
|
m.AckHandle = bf.ReadUint32()
|
||||||
|
m.Unk0 = bf.ReadUint32()
|
||||||
|
m.Unk1 = bf.ReadInt32()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build builds a binary packet from the current data.
|
// Build builds a binary packet from the current data.
|
||||||
|
|||||||
@@ -1,15 +1,22 @@
|
|||||||
package mhfpacket
|
package mhfpacket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfGetFixedSeibatuRankingTable represents the MSG_MHF_GET_FIXED_SEIBATU_RANKING_TABLE
|
// MsgMhfGetFixedSeibatuRankingTable represents the MSG_MHF_GET_FIXED_SEIBATU_RANKING_TABLE
|
||||||
type MsgMhfGetFixedSeibatuRankingTable struct{}
|
type MsgMhfGetFixedSeibatuRankingTable struct {
|
||||||
|
AckHandle uint32
|
||||||
|
Unk0 uint32
|
||||||
|
Unk1 int32
|
||||||
|
Unk2 int32
|
||||||
|
Unk3 int32
|
||||||
|
Unk4 int32
|
||||||
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
func (m *MsgMhfGetFixedSeibatuRankingTable) Opcode() network.PacketID {
|
func (m *MsgMhfGetFixedSeibatuRankingTable) Opcode() network.PacketID {
|
||||||
@@ -18,7 +25,13 @@ func (m *MsgMhfGetFixedSeibatuRankingTable) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfGetFixedSeibatuRankingTable) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfGetFixedSeibatuRankingTable) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
return errors.New("NOT IMPLEMENTED")
|
m.AckHandle = bf.ReadUint32()
|
||||||
|
m.Unk0 = bf.ReadUint32()
|
||||||
|
m.Unk1 = bf.ReadInt32()
|
||||||
|
m.Unk2 = bf.ReadInt32()
|
||||||
|
m.Unk3 = bf.ReadInt32()
|
||||||
|
m.Unk4 = bf.ReadInt32()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build builds a binary packet from the current data.
|
// Build builds a binary packet from the current data.
|
||||||
|
|||||||
@@ -11,8 +11,13 @@ import (
|
|||||||
// MsgMhfGetGemInfo represents the MSG_MHF_GET_GEM_INFO
|
// MsgMhfGetGemInfo represents the MSG_MHF_GET_GEM_INFO
|
||||||
type MsgMhfGetGemInfo struct {
|
type MsgMhfGetGemInfo struct {
|
||||||
AckHandle uint32
|
AckHandle uint32
|
||||||
Unk uint32
|
Unk0 uint32
|
||||||
Unk1 []byte
|
Unk1 uint32
|
||||||
|
Unk2 int32
|
||||||
|
Unk3 int32
|
||||||
|
Unk4 int32
|
||||||
|
Unk5 int32
|
||||||
|
Unk6 int32
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
@@ -23,8 +28,13 @@ func (m *MsgMhfGetGemInfo) Opcode() network.PacketID {
|
|||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfGetGemInfo) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfGetGemInfo) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
m.AckHandle = bf.ReadUint32()
|
m.AckHandle = bf.ReadUint32()
|
||||||
m.Unk = bf.ReadUint32()
|
m.Unk0 = bf.ReadUint32()
|
||||||
m.Unk1 = bf.ReadBytes(24)
|
m.Unk1 = bf.ReadUint32()
|
||||||
|
m.Unk2 = bf.ReadInt32()
|
||||||
|
m.Unk3 = bf.ReadInt32()
|
||||||
|
m.Unk4 = bf.ReadInt32()
|
||||||
|
m.Unk5 = bf.ReadInt32()
|
||||||
|
m.Unk6 = bf.ReadInt32()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
package mhfpacket
|
package mhfpacket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfGetNotice represents the MSG_MHF_GET_NOTICE
|
// MsgMhfGetNotice represents the MSG_MHF_GET_NOTICE
|
||||||
type MsgMhfGetNotice struct{}
|
type MsgMhfGetNotice struct {
|
||||||
|
AckHandle uint32
|
||||||
|
Unk0 uint32
|
||||||
|
Unk1 uint32
|
||||||
|
Unk2 int32
|
||||||
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
func (m *MsgMhfGetNotice) Opcode() network.PacketID {
|
func (m *MsgMhfGetNotice) Opcode() network.PacketID {
|
||||||
@@ -18,7 +23,11 @@ func (m *MsgMhfGetNotice) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfGetNotice) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfGetNotice) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
return errors.New("NOT IMPLEMENTED")
|
m.AckHandle = bf.ReadUint32()
|
||||||
|
m.Unk0 = bf.ReadUint32()
|
||||||
|
m.Unk1 = bf.ReadUint32()
|
||||||
|
m.Unk2 = bf.ReadInt32()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build builds a binary packet from the current data.
|
// Build builds a binary packet from the current data.
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ import (
|
|||||||
// MsgMhfGetRyoudama represents the MSG_MHF_GET_RYOUDAMA
|
// MsgMhfGetRyoudama represents the MSG_MHF_GET_RYOUDAMA
|
||||||
type MsgMhfGetRyoudama struct {
|
type MsgMhfGetRyoudama struct {
|
||||||
AckHandle uint32
|
AckHandle uint32
|
||||||
Unk0 uint8
|
Request1 uint8
|
||||||
Unk1 uint8
|
Request2 uint8
|
||||||
GuildID uint32
|
GuildID uint32
|
||||||
Unk3 uint8
|
Unk3 uint8
|
||||||
}
|
}
|
||||||
@@ -25,8 +25,8 @@ func (m *MsgMhfGetRyoudama) Opcode() network.PacketID {
|
|||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfGetRyoudama) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfGetRyoudama) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
m.AckHandle = bf.ReadUint32()
|
m.AckHandle = bf.ReadUint32()
|
||||||
m.Unk0 = bf.ReadUint8()
|
m.Request1 = bf.ReadUint8()
|
||||||
m.Unk1 = bf.ReadUint8()
|
m.Request2 = bf.ReadUint8()
|
||||||
m.GuildID = bf.ReadUint32()
|
m.GuildID = bf.ReadUint32()
|
||||||
m.Unk3 = bf.ReadUint8()
|
m.Unk3 = bf.ReadUint8()
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -1,20 +1,19 @@
|
|||||||
package mhfpacket
|
package mhfpacket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfGetSeibattle represents the MSG_MHF_GET_SEIBATTLE
|
// MsgMhfGetSeibattle represents the MSG_MHF_GET_SEIBATTLE
|
||||||
type MsgMhfGetSeibattle struct {
|
type MsgMhfGetSeibattle struct {
|
||||||
// Communicator type, multi-format. This might be valid for only one type.
|
|
||||||
AckHandle uint32
|
AckHandle uint32
|
||||||
Unk0 uint8
|
Unk0 uint8
|
||||||
Unk1 uint8
|
Type uint8
|
||||||
Unk2 uint32 // Some shared ID with MSG_SYS_RECORD_LOG, world ID?
|
GuildID uint32
|
||||||
Unk3 uint8
|
Unk3 uint8
|
||||||
Unk4 uint16
|
Unk4 uint16
|
||||||
}
|
}
|
||||||
@@ -28,8 +27,8 @@ func (m *MsgMhfGetSeibattle) Opcode() network.PacketID {
|
|||||||
func (m *MsgMhfGetSeibattle) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfGetSeibattle) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
m.AckHandle = bf.ReadUint32()
|
m.AckHandle = bf.ReadUint32()
|
||||||
m.Unk0 = bf.ReadUint8()
|
m.Unk0 = bf.ReadUint8()
|
||||||
m.Unk1 = bf.ReadUint8()
|
m.Type = bf.ReadUint8()
|
||||||
m.Unk2 = bf.ReadUint32()
|
m.GuildID = bf.ReadUint32()
|
||||||
m.Unk3 = bf.ReadUint8()
|
m.Unk3 = bf.ReadUint8()
|
||||||
m.Unk4 = bf.ReadUint16()
|
m.Unk4 = bf.ReadUint16()
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -1,20 +1,21 @@
|
|||||||
package mhfpacket
|
package mhfpacket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfGetTenrouirai represents the MSG_MHF_GET_TENROUIRAI
|
// MsgMhfGetTenrouirai represents the MSG_MHF_GET_TENROUIRAI
|
||||||
type MsgMhfGetTenrouirai struct {
|
type MsgMhfGetTenrouirai struct {
|
||||||
// Communicator type, multi-format. This might be valid for only one type.
|
|
||||||
AckHandle uint32
|
AckHandle uint32
|
||||||
Unk0 uint16
|
Unk0 uint8
|
||||||
Unk1 uint32
|
Unk1 uint8
|
||||||
Unk2 uint16
|
GuildID uint32
|
||||||
|
Unk3 uint8
|
||||||
|
Unk4 uint8
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
@@ -25,9 +26,11 @@ func (m *MsgMhfGetTenrouirai) Opcode() network.PacketID {
|
|||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfGetTenrouirai) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfGetTenrouirai) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
m.AckHandle = bf.ReadUint32()
|
m.AckHandle = bf.ReadUint32()
|
||||||
m.Unk0 = bf.ReadUint16()
|
m.Unk0 = bf.ReadUint8()
|
||||||
m.Unk1 = bf.ReadUint32()
|
m.Unk1 = bf.ReadUint8()
|
||||||
m.Unk2 = bf.ReadUint16()
|
m.GuildID = bf.ReadUint32()
|
||||||
|
m.Unk3 = bf.ReadUint8()
|
||||||
|
m.Unk4 = bf.ReadUint8()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,20 @@
|
|||||||
package mhfpacket
|
package mhfpacket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfGetTinyBin represents the MSG_MHF_GET_TINY_BIN
|
// MsgMhfGetTinyBin represents the MSG_MHF_GET_TINY_BIN
|
||||||
type MsgMhfGetTinyBin struct {
|
type MsgMhfGetTinyBin struct {
|
||||||
// Communicator type, multi-format. This might be valid for only one type.
|
// Communicator type, multi-format. This might be valid for only one type.
|
||||||
AckHandle uint32
|
AckHandle uint32
|
||||||
Unk0 uint16
|
Unk0 uint8
|
||||||
Unk1 uint8
|
Unk1 uint8
|
||||||
|
Unk2 uint8
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
@@ -24,8 +25,9 @@ func (m *MsgMhfGetTinyBin) Opcode() network.PacketID {
|
|||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfGetTinyBin) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfGetTinyBin) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
m.AckHandle = bf.ReadUint32()
|
m.AckHandle = bf.ReadUint32()
|
||||||
m.Unk0 = bf.ReadUint16()
|
m.Unk0 = bf.ReadUint8()
|
||||||
m.Unk1 = bf.ReadUint8()
|
m.Unk1 = bf.ReadUint8()
|
||||||
|
m.Unk2 = bf.ReadUint8()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,19 +8,8 @@ import (
|
|||||||
"erupe-ce/network/clientctx"
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// The server sends different responses based on these values.
|
|
||||||
const (
|
|
||||||
TowerInfoTypeUnk0 = iota
|
|
||||||
TowerInfoTypeTowerRankPoint
|
|
||||||
TowerInfoTypeGetOwnTowerSkill
|
|
||||||
TowerInfoTypeGetOwnTowerLevelV3
|
|
||||||
TowerInfoTypeTowerTouhaHistory
|
|
||||||
TowerInfoTypeUnk5
|
|
||||||
)
|
|
||||||
|
|
||||||
// MsgMhfGetTowerInfo represents the MSG_MHF_GET_TOWER_INFO
|
// MsgMhfGetTowerInfo represents the MSG_MHF_GET_TOWER_INFO
|
||||||
type MsgMhfGetTowerInfo struct {
|
type MsgMhfGetTowerInfo struct {
|
||||||
// Communicator type, multi-format. This might be valid for only one type.
|
|
||||||
AckHandle uint32
|
AckHandle uint32
|
||||||
InfoType uint32 // Requested response type
|
InfoType uint32 // Requested response type
|
||||||
Unk0 uint32
|
Unk0 uint32
|
||||||
|
|||||||
@@ -1,15 +1,24 @@
|
|||||||
package mhfpacket
|
package mhfpacket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfPostGemInfo represents the MSG_MHF_POST_GEM_INFO
|
// MsgMhfPostGemInfo represents the MSG_MHF_POST_GEM_INFO
|
||||||
type MsgMhfPostGemInfo struct{}
|
type MsgMhfPostGemInfo struct {
|
||||||
|
AckHandle uint32
|
||||||
|
Op uint32
|
||||||
|
Unk1 uint32
|
||||||
|
Gem int32
|
||||||
|
Quantity int32
|
||||||
|
CID int32
|
||||||
|
Message int32
|
||||||
|
Unk6 int32
|
||||||
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
func (m *MsgMhfPostGemInfo) Opcode() network.PacketID {
|
func (m *MsgMhfPostGemInfo) Opcode() network.PacketID {
|
||||||
@@ -18,7 +27,15 @@ func (m *MsgMhfPostGemInfo) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfPostGemInfo) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfPostGemInfo) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
return errors.New("NOT IMPLEMENTED")
|
m.AckHandle = bf.ReadUint32()
|
||||||
|
m.Op = bf.ReadUint32()
|
||||||
|
m.Unk1 = bf.ReadUint32()
|
||||||
|
m.Gem = bf.ReadInt32()
|
||||||
|
m.Quantity = bf.ReadInt32()
|
||||||
|
m.CID = bf.ReadInt32()
|
||||||
|
m.Message = bf.ReadInt32()
|
||||||
|
m.Unk6 = bf.ReadInt32()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build builds a binary packet from the current data.
|
// Build builds a binary packet from the current data.
|
||||||
|
|||||||
@@ -1,15 +1,21 @@
|
|||||||
package mhfpacket
|
package mhfpacket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfPostNotice represents the MSG_MHF_POST_NOTICE
|
// MsgMhfPostNotice represents the MSG_MHF_POST_NOTICE
|
||||||
type MsgMhfPostNotice struct{}
|
type MsgMhfPostNotice struct {
|
||||||
|
AckHandle uint32
|
||||||
|
Unk0 uint32
|
||||||
|
Unk1 uint32
|
||||||
|
Unk2 int32
|
||||||
|
Unk3 int32
|
||||||
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
func (m *MsgMhfPostNotice) Opcode() network.PacketID {
|
func (m *MsgMhfPostNotice) Opcode() network.PacketID {
|
||||||
@@ -18,7 +24,12 @@ func (m *MsgMhfPostNotice) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfPostNotice) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfPostNotice) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
return errors.New("NOT IMPLEMENTED")
|
m.AckHandle = bf.ReadUint32()
|
||||||
|
m.Unk0 = bf.ReadUint32()
|
||||||
|
m.Unk1 = bf.ReadUint32()
|
||||||
|
m.Unk2 = bf.ReadInt32()
|
||||||
|
m.Unk3 = bf.ReadInt32()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build builds a binary packet from the current data.
|
// Build builds a binary packet from the current data.
|
||||||
|
|||||||
@@ -1,22 +1,34 @@
|
|||||||
package mhfpacket
|
package mhfpacket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfPostTenrouirai represents the MSG_MHF_POST_TENROUIRAI
|
// MsgMhfPostTenrouirai represents the MSG_MHF_POST_TENROUIRAI
|
||||||
type MsgMhfPostTenrouirai struct{
|
type MsgMhfPostTenrouirai struct {
|
||||||
AckHandle uint32
|
AckHandle uint32
|
||||||
Unk0 uint16
|
Unk0 uint8
|
||||||
Unk1 uint32
|
Op uint8
|
||||||
Unk2 uint32
|
GuildID uint32
|
||||||
Unk3 uint32
|
Unk1 uint8
|
||||||
Unk4 uint32
|
|
||||||
Unk5 uint8
|
Floors uint16
|
||||||
|
Antiques uint16
|
||||||
|
Chests uint16
|
||||||
|
Cats uint16
|
||||||
|
TRP uint16
|
||||||
|
Slays uint16
|
||||||
|
|
||||||
|
DonatedRP uint16
|
||||||
|
PreviousRP uint16
|
||||||
|
Unk2_0 uint16
|
||||||
|
Unk2_1 uint16
|
||||||
|
Unk2_2 uint16
|
||||||
|
Unk2_3 uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
@@ -27,12 +39,28 @@ func (m *MsgMhfPostTenrouirai) Opcode() network.PacketID {
|
|||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfPostTenrouirai) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfPostTenrouirai) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
m.AckHandle = bf.ReadUint32()
|
m.AckHandle = bf.ReadUint32()
|
||||||
m.Unk0 = bf.ReadUint16()
|
m.Unk0 = bf.ReadUint8()
|
||||||
m.Unk1 = bf.ReadUint32()
|
m.Op = bf.ReadUint8()
|
||||||
m.Unk2 = bf.ReadUint32()
|
m.GuildID = bf.ReadUint32()
|
||||||
m.Unk3 = bf.ReadUint32()
|
m.Unk1 = bf.ReadUint8()
|
||||||
m.Unk4 = bf.ReadUint32()
|
|
||||||
m.Unk5 = bf.ReadUint8()
|
switch m.Op {
|
||||||
|
case 1:
|
||||||
|
m.Floors = bf.ReadUint16()
|
||||||
|
m.Antiques = bf.ReadUint16()
|
||||||
|
m.Chests = bf.ReadUint16()
|
||||||
|
m.Cats = bf.ReadUint16()
|
||||||
|
m.TRP = bf.ReadUint16()
|
||||||
|
m.Slays = bf.ReadUint16()
|
||||||
|
case 2:
|
||||||
|
m.DonatedRP = bf.ReadUint16()
|
||||||
|
m.PreviousRP = bf.ReadUint16()
|
||||||
|
m.Unk2_0 = bf.ReadUint16()
|
||||||
|
m.Unk2_1 = bf.ReadUint16()
|
||||||
|
m.Unk2_2 = bf.ReadUint16()
|
||||||
|
m.Unk2_3 = bf.ReadUint16()
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,10 @@ import (
|
|||||||
// MsgMhfPostTinyBin represents the MSG_MHF_POST_TINY_BIN
|
// MsgMhfPostTinyBin represents the MSG_MHF_POST_TINY_BIN
|
||||||
type MsgMhfPostTinyBin struct {
|
type MsgMhfPostTinyBin struct {
|
||||||
AckHandle uint32
|
AckHandle uint32
|
||||||
Unk0 uint16
|
Unk0 uint8
|
||||||
Unk1 uint8
|
Unk1 uint8
|
||||||
Unk2 uint8
|
Unk2 uint8
|
||||||
|
Unk3 uint8
|
||||||
Data []byte
|
Data []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,9 +26,10 @@ func (m *MsgMhfPostTinyBin) Opcode() network.PacketID {
|
|||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfPostTinyBin) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfPostTinyBin) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
m.AckHandle = bf.ReadUint32()
|
m.AckHandle = bf.ReadUint32()
|
||||||
m.Unk0 = bf.ReadUint16()
|
m.Unk0 = bf.ReadUint8()
|
||||||
m.Unk1 = bf.ReadUint8()
|
m.Unk1 = bf.ReadUint8()
|
||||||
m.Unk2 = bf.ReadUint8()
|
m.Unk2 = bf.ReadUint8()
|
||||||
|
m.Unk3 = bf.ReadUint8()
|
||||||
m.Data = bf.ReadBytes(uint(bf.ReadUint16()))
|
m.Data = bf.ReadBytes(uint(bf.ReadUint16()))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +1,26 @@
|
|||||||
package mhfpacket
|
package mhfpacket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfPostTowerInfo represents the MSG_MHF_POST_TOWER_INFO
|
// MsgMhfPostTowerInfo represents the MSG_MHF_POST_TOWER_INFO
|
||||||
type MsgMhfPostTowerInfo struct {
|
type MsgMhfPostTowerInfo struct {
|
||||||
// Communicator type, multi-format. This might be valid for only one type.
|
|
||||||
AckHandle uint32
|
AckHandle uint32
|
||||||
Unk0 uint32
|
InfoType uint32
|
||||||
Unk1 uint32
|
Unk1 uint32
|
||||||
Unk2 uint32
|
Skill int32
|
||||||
Unk3 uint32
|
TR int32
|
||||||
Unk4 uint32
|
TRP int32
|
||||||
Unk5 uint32
|
Cost int32
|
||||||
Unk6 uint32
|
Unk6 int32
|
||||||
Unk7 uint32
|
Unk7 int32
|
||||||
Unk8 uint32
|
Block1 int32
|
||||||
Unk9 uint32
|
Unk9 int64
|
||||||
Unk10 uint32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
@@ -33,17 +31,16 @@ func (m *MsgMhfPostTowerInfo) Opcode() network.PacketID {
|
|||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfPostTowerInfo) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfPostTowerInfo) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
m.AckHandle = bf.ReadUint32()
|
m.AckHandle = bf.ReadUint32()
|
||||||
m.Unk0 = bf.ReadUint32()
|
m.InfoType = bf.ReadUint32()
|
||||||
m.Unk1 = bf.ReadUint32()
|
m.Unk1 = bf.ReadUint32()
|
||||||
m.Unk2 = bf.ReadUint32()
|
m.Skill = bf.ReadInt32()
|
||||||
m.Unk3 = bf.ReadUint32()
|
m.TR = bf.ReadInt32()
|
||||||
m.Unk4 = bf.ReadUint32()
|
m.TRP = bf.ReadInt32()
|
||||||
m.Unk5 = bf.ReadUint32()
|
m.Cost = bf.ReadInt32()
|
||||||
m.Unk6 = bf.ReadUint32()
|
m.Unk6 = bf.ReadInt32()
|
||||||
m.Unk7 = bf.ReadUint32()
|
m.Unk7 = bf.ReadInt32()
|
||||||
m.Unk8 = bf.ReadUint32()
|
m.Block1 = bf.ReadInt32()
|
||||||
m.Unk9 = bf.ReadUint32()
|
m.Unk9 = bf.ReadInt64()
|
||||||
m.Unk10 = bf.ReadUint32()
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,7 @@ type MsgMhfPresentBox struct {
|
|||||||
Unk4 uint32
|
Unk4 uint32
|
||||||
Unk5 uint32
|
Unk5 uint32
|
||||||
Unk6 uint32
|
Unk6 uint32
|
||||||
Unk7 uint32
|
Unk7 []uint32
|
||||||
Unk8 uint32
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
@@ -37,8 +36,9 @@ func (m *MsgMhfPresentBox) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientC
|
|||||||
m.Unk4 = bf.ReadUint32()
|
m.Unk4 = bf.ReadUint32()
|
||||||
m.Unk5 = bf.ReadUint32()
|
m.Unk5 = bf.ReadUint32()
|
||||||
m.Unk6 = bf.ReadUint32()
|
m.Unk6 = bf.ReadUint32()
|
||||||
m.Unk7 = bf.ReadUint32()
|
for i := uint32(0); i < m.Unk2; i++ {
|
||||||
m.Unk8 = bf.ReadUint32()
|
m.Unk7 = append(m.Unk7, bf.ReadUint32())
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
package mhfpacket
|
package mhfpacket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfReadBeatLevelAllRanking represents the MSG_MHF_READ_BEAT_LEVEL_ALL_RANKING
|
// MsgMhfReadBeatLevelAllRanking represents the MSG_MHF_READ_BEAT_LEVEL_ALL_RANKING
|
||||||
type MsgMhfReadBeatLevelAllRanking struct{}
|
type MsgMhfReadBeatLevelAllRanking struct {
|
||||||
|
AckHandle uint32
|
||||||
|
Unk0 uint32
|
||||||
|
GuildID int32
|
||||||
|
Unk2 int32
|
||||||
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
func (m *MsgMhfReadBeatLevelAllRanking) Opcode() network.PacketID {
|
func (m *MsgMhfReadBeatLevelAllRanking) Opcode() network.PacketID {
|
||||||
@@ -18,7 +23,11 @@ func (m *MsgMhfReadBeatLevelAllRanking) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfReadBeatLevelAllRanking) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfReadBeatLevelAllRanking) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
return errors.New("NOT IMPLEMENTED")
|
m.AckHandle = bf.ReadUint32()
|
||||||
|
m.Unk0 = bf.ReadUint32()
|
||||||
|
m.GuildID = bf.ReadInt32()
|
||||||
|
m.Unk2 = bf.ReadInt32()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build builds a binary packet from the current data.
|
// Build builds a binary packet from the current data.
|
||||||
|
|||||||
@@ -1,15 +1,20 @@
|
|||||||
package mhfpacket
|
package mhfpacket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfReadBeatLevelMyRanking represents the MSG_MHF_READ_BEAT_LEVEL_MY_RANKING
|
// MsgMhfReadBeatLevelMyRanking represents the MSG_MHF_READ_BEAT_LEVEL_MY_RANKING
|
||||||
type MsgMhfReadBeatLevelMyRanking struct{}
|
type MsgMhfReadBeatLevelMyRanking struct {
|
||||||
|
AckHandle uint32
|
||||||
|
Unk0 uint32
|
||||||
|
Unk1 uint32
|
||||||
|
Unk2 []int32
|
||||||
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
func (m *MsgMhfReadBeatLevelMyRanking) Opcode() network.PacketID {
|
func (m *MsgMhfReadBeatLevelMyRanking) Opcode() network.PacketID {
|
||||||
@@ -18,7 +23,13 @@ func (m *MsgMhfReadBeatLevelMyRanking) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfReadBeatLevelMyRanking) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfReadBeatLevelMyRanking) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
return errors.New("NOT IMPLEMENTED")
|
m.AckHandle = bf.ReadUint32()
|
||||||
|
m.Unk0 = bf.ReadUint32()
|
||||||
|
m.Unk1 = bf.ReadUint32()
|
||||||
|
for i := 0; i < 16; i++ {
|
||||||
|
m.Unk2 = append(m.Unk2, bf.ReadInt32())
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build builds a binary packet from the current data.
|
// Build builds a binary packet from the current data.
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package mhfpacket
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
_config "erupe-ce/config"
|
||||||
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
"erupe-ce/network"
|
"erupe-ce/network"
|
||||||
@@ -34,12 +35,14 @@ func (m *MsgMhfStampcardStamp) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Cli
|
|||||||
m.GR = bf.ReadUint16()
|
m.GR = bf.ReadUint16()
|
||||||
m.Stamps = bf.ReadUint16()
|
m.Stamps = bf.ReadUint16()
|
||||||
_ = bf.ReadUint16()
|
_ = bf.ReadUint16()
|
||||||
m.Reward1 = uint16(bf.ReadUint32())
|
if _config.ErupeConfig.ClientMode != _config.Z1 {
|
||||||
m.Reward2 = uint16(bf.ReadUint32())
|
m.Reward1 = uint16(bf.ReadUint32())
|
||||||
m.Item1 = uint16(bf.ReadUint32())
|
m.Reward2 = uint16(bf.ReadUint32())
|
||||||
m.Item2 = uint16(bf.ReadUint32())
|
m.Item1 = uint16(bf.ReadUint32())
|
||||||
m.Quantity1 = uint16(bf.ReadUint32())
|
m.Item2 = uint16(bf.ReadUint32())
|
||||||
m.Quantity2 = uint16(bf.ReadUint32())
|
m.Quantity1 = uint16(bf.ReadUint32())
|
||||||
|
m.Quantity2 = uint16(bf.ReadUint32())
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
29
patch-schema/tower.sql
Normal file
29
patch-schema/tower.sql
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
BEGIN;
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS tower (
|
||||||
|
char_id INT,
|
||||||
|
tr INT,
|
||||||
|
trp INT,
|
||||||
|
tsp INT,
|
||||||
|
block1 INT,
|
||||||
|
block2 INT,
|
||||||
|
skills TEXT DEFAULT '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0',
|
||||||
|
gems TEXT DEFAULT '0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0'
|
||||||
|
);
|
||||||
|
|
||||||
|
ALTER TABLE IF EXISTS guild_characters
|
||||||
|
ADD COLUMN IF NOT EXISTS tower_mission_1 INT;
|
||||||
|
|
||||||
|
ALTER TABLE IF EXISTS guild_characters
|
||||||
|
ADD COLUMN IF NOT EXISTS tower_mission_2 INT;
|
||||||
|
|
||||||
|
ALTER TABLE IF EXISTS guild_characters
|
||||||
|
ADD COLUMN IF NOT EXISTS tower_mission_3 INT;
|
||||||
|
|
||||||
|
ALTER TABLE IF EXISTS guilds
|
||||||
|
ADD COLUMN IF NOT EXISTS tower_mission_page INT DEFAULT 1;
|
||||||
|
|
||||||
|
ALTER TABLE IF EXISTS guilds
|
||||||
|
ADD COLUMN IF NOT EXISTS tower_rp INT DEFAULT 0;
|
||||||
|
|
||||||
|
END;
|
||||||
@@ -27,15 +27,16 @@ func stubEnumerateNoResults(s *Session, ackHandle uint32) {
|
|||||||
doAckBufSucceed(s, ackHandle, enumBf.Data())
|
doAckBufSucceed(s, ackHandle, enumBf.Data())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Temporary function to just return no results for many MSG_MHF_GET* packets.
|
func doAckEarthSucceed(s *Session, ackHandle uint32, data []*byteframe.ByteFrame) {
|
||||||
func stubGetNoResults(s *Session, ackHandle uint32) {
|
bf := byteframe.NewByteFrame()
|
||||||
resp := byteframe.NewByteFrame()
|
bf.WriteUint32(uint32(s.server.erupeConfig.DevModeOptions.EarthIDOverride))
|
||||||
resp.WriteUint32(0x0A218EAD) // Unk shared ID. Sent in response of MSG_MHF_GET_TOWER_INFO, MSG_MHF_GET_PAPER_DATA etc. (World ID?)
|
bf.WriteUint32(0)
|
||||||
resp.WriteUint32(0) // Unk
|
bf.WriteUint32(0)
|
||||||
resp.WriteUint32(0) // Unk
|
bf.WriteUint32(uint32(len(data)))
|
||||||
resp.WriteUint32(0) // Entry count
|
for i := range data {
|
||||||
|
bf.WriteBytes(data[i].Data())
|
||||||
doAckBufSucceed(s, ackHandle, resp.Data())
|
}
|
||||||
|
doAckBufSucceed(s, ackHandle, bf.Data())
|
||||||
}
|
}
|
||||||
|
|
||||||
func doAckBufSucceed(s *Session, ackHandle uint32, data []byte) {
|
func doAckBufSucceed(s *Session, ackHandle uint32, data []byte) {
|
||||||
@@ -1574,46 +1575,16 @@ func handleMsgMhfStampcardPrize(s *Session, p mhfpacket.MHFPacket) {}
|
|||||||
|
|
||||||
func handleMsgMhfUnreserveSrg(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgMhfUnreserveSrg(s *Session, p mhfpacket.MHFPacket) {}
|
||||||
|
|
||||||
func handleMsgMhfReadBeatLevel(s *Session, p mhfpacket.MHFPacket) {
|
|
||||||
pkt := p.(*mhfpacket.MsgMhfReadBeatLevel)
|
|
||||||
|
|
||||||
// This response is fixed and will never change on JP,
|
|
||||||
// but I've left it dynamic for possible other client differences.
|
|
||||||
resp := byteframe.NewByteFrame()
|
|
||||||
for i := 0; i < int(pkt.ValidIDCount); i++ {
|
|
||||||
resp.WriteUint32(pkt.IDs[i])
|
|
||||||
resp.WriteUint32(1)
|
|
||||||
resp.WriteUint32(1)
|
|
||||||
resp.WriteUint32(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleMsgMhfUpdateBeatLevel(s *Session, p mhfpacket.MHFPacket) {
|
|
||||||
pkt := p.(*mhfpacket.MsgMhfUpdateBeatLevel)
|
|
||||||
|
|
||||||
doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleMsgMhfReadBeatLevelAllRanking(s *Session, p mhfpacket.MHFPacket) {}
|
|
||||||
|
|
||||||
func handleMsgMhfReadBeatLevelMyRanking(s *Session, p mhfpacket.MHFPacket) {}
|
|
||||||
|
|
||||||
func handleMsgMhfReadLastWeekBeatRanking(s *Session, p mhfpacket.MHFPacket) {}
|
|
||||||
|
|
||||||
func handleMsgMhfGetFixedSeibatuRankingTable(s *Session, p mhfpacket.MHFPacket) {}
|
|
||||||
|
|
||||||
func handleMsgMhfKickExportForce(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgMhfKickExportForce(s *Session, p mhfpacket.MHFPacket) {}
|
||||||
|
|
||||||
func handleMsgMhfGetEarthStatus(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfGetEarthStatus(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfGetEarthStatus)
|
pkt := p.(*mhfpacket.MsgMhfGetEarthStatus)
|
||||||
bf := byteframe.NewByteFrame()
|
bf := byteframe.NewByteFrame()
|
||||||
bf.WriteUint32(uint32(TimeWeekStart().Unix())) // Start
|
bf.WriteUint32(uint32(TimeWeekStart().Add(time.Hour * -24).Unix())) // Start
|
||||||
bf.WriteUint32(uint32(TimeWeekNext().Unix())) // End
|
bf.WriteUint32(uint32(TimeWeekNext().Add(time.Hour * 24).Unix())) // End
|
||||||
bf.WriteInt32(s.server.erupeConfig.DevModeOptions.EarthStatusOverride)
|
bf.WriteInt32(s.server.erupeConfig.DevModeOptions.EarthStatusOverride)
|
||||||
bf.WriteInt32(21)
|
bf.WriteInt32(s.server.erupeConfig.DevModeOptions.EarthIDOverride)
|
||||||
bf.WriteInt32(0)
|
bf.WriteInt32(s.server.erupeConfig.DevModeOptions.EarthMonsterOverride)
|
||||||
bf.WriteInt32(0)
|
bf.WriteInt32(0)
|
||||||
bf.WriteInt32(0)
|
bf.WriteInt32(0)
|
||||||
bf.WriteInt32(0)
|
bf.WriteInt32(0)
|
||||||
@@ -1624,86 +1595,183 @@ func handleMsgMhfRegistSpabiTime(s *Session, p mhfpacket.MHFPacket) {}
|
|||||||
|
|
||||||
func handleMsgMhfGetEarthValue(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfGetEarthValue(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfGetEarthValue)
|
pkt := p.(*mhfpacket.MsgMhfGetEarthValue)
|
||||||
var earthValues []struct{ Unk0, Unk1, Unk2, Unk3, Unk4, Unk5 uint32 }
|
type EarthValues struct {
|
||||||
if pkt.ReqType == 3 {
|
Value []uint32
|
||||||
earthValues = []struct {
|
}
|
||||||
Unk0, Unk1, Unk2, Unk3, Unk4, Unk5 uint32
|
|
||||||
}{
|
var earthValues []EarthValues
|
||||||
// TW identical to JP
|
switch pkt.ReqType {
|
||||||
{
|
case 1:
|
||||||
Unk0: 0x03E9,
|
earthValues = []EarthValues{
|
||||||
Unk1: 0x24,
|
{[]uint32{1, 312, 0, 0, 0, 0}},
|
||||||
},
|
{[]uint32{2, 99, 0, 0, 0, 0}},
|
||||||
{
|
|
||||||
Unk0: 0x2329,
|
|
||||||
Unk1: 0x03,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Unk0: 0x232A,
|
|
||||||
Unk1: 0x0A,
|
|
||||||
Unk2: 0x012C,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
} else if pkt.ReqType == 2 {
|
case 2:
|
||||||
earthValues = []struct {
|
earthValues = []EarthValues{
|
||||||
Unk0, Unk1, Unk2, Unk3, Unk4, Unk5 uint32
|
{[]uint32{1, 5771, 0, 0, 0, 0}},
|
||||||
}{
|
{[]uint32{2, 1847, 0, 0, 0, 0}},
|
||||||
// JP response was empty
|
|
||||||
{
|
|
||||||
Unk0: 0x01,
|
|
||||||
Unk1: 0x168B,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Unk0: 0x02,
|
|
||||||
Unk1: 0x0737,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
} else if pkt.ReqType == 1 {
|
case 3:
|
||||||
earthValues = []struct {
|
earthValues = []EarthValues{
|
||||||
Unk0, Unk1, Unk2, Unk3, Unk4, Unk5 uint32
|
{[]uint32{1001, 36, 0, 0, 0, 0}},
|
||||||
}{
|
{[]uint32{9001, 3, 0, 0, 0, 0}},
|
||||||
// JP simply sent 01 and 02 respectively
|
{[]uint32{9002, 10, 300, 0, 0, 0}},
|
||||||
{
|
|
||||||
Unk0: 0x01,
|
|
||||||
Unk1: 0x0138,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Unk0: 0x02,
|
|
||||||
Unk1: 0x63,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resp := byteframe.NewByteFrame()
|
var data []*byteframe.ByteFrame
|
||||||
resp.WriteUint32(0x0A218EAD) // Unk shared ID. Sent in response of MSG_MHF_GET_TOWER_INFO, MSG_MHF_GET_PAPER_DATA etc.
|
for _, i := range earthValues {
|
||||||
resp.WriteUint32(0) // Unk
|
bf := byteframe.NewByteFrame()
|
||||||
resp.WriteUint32(0) // Unk
|
for _, j := range i.Value {
|
||||||
resp.WriteUint32(uint32(len(earthValues))) // value count
|
bf.WriteUint32(j)
|
||||||
for _, v := range earthValues {
|
}
|
||||||
resp.WriteUint32(v.Unk0)
|
data = append(data, bf)
|
||||||
resp.WriteUint32(v.Unk1)
|
|
||||||
resp.WriteUint32(v.Unk2)
|
|
||||||
resp.WriteUint32(v.Unk3)
|
|
||||||
resp.WriteUint32(v.Unk4)
|
|
||||||
resp.WriteUint32(v.Unk5)
|
|
||||||
}
|
}
|
||||||
|
doAckEarthSucceed(s, pkt.AckHandle, data)
|
||||||
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfDebugPostValue(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgMhfDebugPostValue(s *Session, p mhfpacket.MHFPacket) {}
|
||||||
|
|
||||||
func handleMsgMhfGetNotice(s *Session, p mhfpacket.MHFPacket) {}
|
|
||||||
|
|
||||||
func handleMsgMhfPostNotice(s *Session, p mhfpacket.MHFPacket) {}
|
|
||||||
|
|
||||||
func handleMsgMhfGetRandFromTable(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgMhfGetRandFromTable(s *Session, p mhfpacket.MHFPacket) {}
|
||||||
|
|
||||||
func handleMsgMhfGetSenyuDailyCount(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgMhfGetSenyuDailyCount(s *Session, p mhfpacket.MHFPacket) {}
|
||||||
|
|
||||||
|
type SeibattleTimetable struct {
|
||||||
|
Start time.Time
|
||||||
|
End time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type SeibattleKeyScore struct {
|
||||||
|
Unk0 uint8
|
||||||
|
Unk1 int32
|
||||||
|
}
|
||||||
|
|
||||||
|
type SeibattleCareer struct {
|
||||||
|
Unk0 uint16
|
||||||
|
Unk1 uint16
|
||||||
|
Unk2 uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
type SeibattleOpponent struct {
|
||||||
|
Unk0 int32
|
||||||
|
Unk1 int8
|
||||||
|
}
|
||||||
|
|
||||||
|
type SeibattleConventionResult struct {
|
||||||
|
Unk0 uint32
|
||||||
|
Unk1 uint16
|
||||||
|
Unk2 uint16
|
||||||
|
Unk3 uint16
|
||||||
|
Unk4 uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
type SeibattleCharScore struct {
|
||||||
|
Unk0 uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type SeibattleCurResult struct {
|
||||||
|
Unk0 uint32
|
||||||
|
Unk1 uint16
|
||||||
|
Unk2 uint16
|
||||||
|
Unk3 uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
type Seibattle struct {
|
||||||
|
Timetable []SeibattleTimetable
|
||||||
|
KeyScore []SeibattleKeyScore
|
||||||
|
Career []SeibattleCareer
|
||||||
|
Opponent []SeibattleOpponent
|
||||||
|
ConventionResult []SeibattleConventionResult
|
||||||
|
CharScore []SeibattleCharScore
|
||||||
|
CurResult []SeibattleCurResult
|
||||||
|
}
|
||||||
|
|
||||||
func handleMsgMhfGetSeibattle(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfGetSeibattle(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfGetSeibattle)
|
pkt := p.(*mhfpacket.MsgMhfGetSeibattle)
|
||||||
stubGetNoResults(s, pkt.AckHandle)
|
var data []*byteframe.ByteFrame
|
||||||
|
seibattle := Seibattle{
|
||||||
|
Timetable: []SeibattleTimetable{
|
||||||
|
{TimeMidnight(), TimeMidnight().Add(time.Hour * 8)},
|
||||||
|
{TimeMidnight().Add(time.Hour * 8), TimeMidnight().Add(time.Hour * 16)},
|
||||||
|
{TimeMidnight().Add(time.Hour * 16), TimeMidnight().Add(time.Hour * 24)},
|
||||||
|
},
|
||||||
|
KeyScore: []SeibattleKeyScore{
|
||||||
|
{0, 0},
|
||||||
|
},
|
||||||
|
Career: []SeibattleCareer{
|
||||||
|
{0, 0, 0},
|
||||||
|
},
|
||||||
|
Opponent: []SeibattleOpponent{
|
||||||
|
{1, 1},
|
||||||
|
},
|
||||||
|
ConventionResult: []SeibattleConventionResult{
|
||||||
|
{0, 0, 0, 0, 0},
|
||||||
|
},
|
||||||
|
CharScore: []SeibattleCharScore{
|
||||||
|
{0},
|
||||||
|
},
|
||||||
|
CurResult: []SeibattleCurResult{
|
||||||
|
{0, 0, 0, 0},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
switch pkt.Type {
|
||||||
|
case 1:
|
||||||
|
for _, timetable := range seibattle.Timetable {
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteUint32(uint32(timetable.Start.Unix()))
|
||||||
|
bf.WriteUint32(uint32(timetable.End.Unix()))
|
||||||
|
data = append(data, bf)
|
||||||
|
}
|
||||||
|
case 3: // Key score?
|
||||||
|
for _, keyScore := range seibattle.KeyScore {
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteUint8(keyScore.Unk0)
|
||||||
|
bf.WriteInt32(keyScore.Unk1)
|
||||||
|
data = append(data, bf)
|
||||||
|
}
|
||||||
|
case 4: // Career?
|
||||||
|
for _, career := range seibattle.Career {
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteUint16(career.Unk0)
|
||||||
|
bf.WriteUint16(career.Unk1)
|
||||||
|
bf.WriteUint16(career.Unk2)
|
||||||
|
data = append(data, bf)
|
||||||
|
}
|
||||||
|
case 5: // Opponent?
|
||||||
|
for _, opponent := range seibattle.Opponent {
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteInt32(opponent.Unk0)
|
||||||
|
bf.WriteInt8(opponent.Unk1)
|
||||||
|
data = append(data, bf)
|
||||||
|
}
|
||||||
|
case 6: // Convention result?
|
||||||
|
for _, conventionResult := range seibattle.ConventionResult {
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteUint32(conventionResult.Unk0)
|
||||||
|
bf.WriteUint16(conventionResult.Unk1)
|
||||||
|
bf.WriteUint16(conventionResult.Unk2)
|
||||||
|
bf.WriteUint16(conventionResult.Unk3)
|
||||||
|
bf.WriteUint16(conventionResult.Unk4)
|
||||||
|
data = append(data, bf)
|
||||||
|
}
|
||||||
|
case 7: // Char score?
|
||||||
|
for _, charScore := range seibattle.CharScore {
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteUint32(charScore.Unk0)
|
||||||
|
data = append(data, bf)
|
||||||
|
}
|
||||||
|
case 8: // Cur result?
|
||||||
|
for _, curResult := range seibattle.CurResult {
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteUint32(curResult.Unk0)
|
||||||
|
bf.WriteUint16(curResult.Unk1)
|
||||||
|
bf.WriteUint16(curResult.Unk2)
|
||||||
|
bf.WriteUint16(curResult.Unk3)
|
||||||
|
data = append(data, bf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doAckEarthSucceed(s, pkt.AckHandle, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfPostSeibattle(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgMhfPostSeibattle(s *Session, p mhfpacket.MHFPacket) {}
|
||||||
|
|||||||
@@ -1,21 +1,73 @@
|
|||||||
package channelserver
|
package channelserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/common/stringsupport"
|
||||||
"erupe-ce/network/mhfpacket"
|
"erupe-ce/network/mhfpacket"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type RyoudamaReward struct {
|
||||||
|
Unk0 uint8
|
||||||
|
Unk1 uint8
|
||||||
|
Unk2 uint16
|
||||||
|
Unk3 uint16
|
||||||
|
Unk4 uint16
|
||||||
|
Unk5 uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
type RyoudamaKeyScore struct {
|
||||||
|
Unk0 uint8
|
||||||
|
Unk1 int32
|
||||||
|
}
|
||||||
|
|
||||||
|
type RyoudamaCharInfo struct {
|
||||||
|
CID uint32
|
||||||
|
Unk0 int32
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
type RyoudamaBoostInfo struct {
|
||||||
|
Start time.Time
|
||||||
|
End time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type Ryoudama struct {
|
||||||
|
Reward []RyoudamaReward
|
||||||
|
KeyScore []RyoudamaKeyScore
|
||||||
|
CharInfo []RyoudamaCharInfo
|
||||||
|
BoostInfo []RyoudamaBoostInfo
|
||||||
|
Score []int32
|
||||||
|
}
|
||||||
|
|
||||||
func handleMsgMhfGetRyoudama(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfGetRyoudama(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfGetRyoudama)
|
pkt := p.(*mhfpacket.MsgMhfGetRyoudama)
|
||||||
// likely guild related
|
var data []*byteframe.ByteFrame
|
||||||
// REQ: 00 04 13 53 8F 18 00
|
ryoudama := Ryoudama{Score: []int32{0}}
|
||||||
// RSP: 0A 21 8E AD 00 00 00 00 00 00 00 00 00 00 00 01 00 01 FE 4E
|
switch pkt.Request2 {
|
||||||
// REQ: 00 06 13 53 8F 18 00
|
case 4:
|
||||||
// RSP: 0A 21 8E AD 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00
|
for _, score := range ryoudama.Score {
|
||||||
// REQ: 00 05 13 53 8F 18 00
|
bf := byteframe.NewByteFrame()
|
||||||
// RSP: 0A 21 8E AD 00 00 00 00 00 00 00 00 00 00 00 0E 2A 15 9E CC 00 00 00 01 82 79 83 4E 83 8A 81 5B 83 69 00 00 00 00 1E 55 B0 2F 00 00 00 01 8D F7 00 00 00 00 00 00 00 00 00 00 00 00 2A 15 9E CC 00 00 00 02 82 79 83 4E 83 8A 81 5B 83 69 00 00 00 00 03 D5 30 56 00 00 00 02 95 BD 91 F2 97 42 00 00 00 00 00 00 00 00 3F 57 76 9F 00 00 00 03 93 56 92 6E 96 B3 97 70 00 00 00 00 00 00 38 D9 0E C4 00 00 00 03 87 64 83 78 83 42 00 00 00 00 00 00 00 00 23 F3 B9 77 00 00 00 04 82 B3 82 CC 82 DC 82 E9 81 99 00 00 00 00 3F 1B 17 9C 00 00 00 04 82 B1 82 A4 82 BD 00 00 00 00 00 00 00 00 00 B9 F9 C0 00 00 00 05 82 CD 82 E9 82 A9 00 00 00 00 00 00 00 00 23 9F 9A EA 00 00 00 05 83 70 83 62 83 4C 83 83 83 49 00 00 00 00 38 D9 0E C4 00 00 00 06 87 64 83 78 83 42 00 00 00 00 00 00 00 00 1E 55 B0 2F 00 00 00 06 8D F7 00 00 00 00 00 00 00 00 00 00 00 00 03 D5 30 56 00 00 00 07 95 BD 91 F2 97 42 00 00 00 00 00 00 00 00 02 D3 B8 77 00 00 00 07 6F 77 6C 32 35 32 35 00 00 00 00 00 00 00
|
bf.WriteInt32(score)
|
||||||
data, _ := hex.DecodeString("0A218EAD0000000000000000000000010000000000000000")
|
data = append(data, bf)
|
||||||
doAckBufSucceed(s, pkt.AckHandle, data)
|
}
|
||||||
|
case 5:
|
||||||
|
for _, info := range ryoudama.CharInfo {
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteUint32(info.CID)
|
||||||
|
bf.WriteInt32(info.Unk0)
|
||||||
|
bf.WriteBytes(stringsupport.PaddedString(info.Name, 14, true))
|
||||||
|
data = append(data, bf)
|
||||||
|
}
|
||||||
|
case 6:
|
||||||
|
for _, info := range ryoudama.BoostInfo {
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteUint32(uint32(info.Start.Unix()))
|
||||||
|
bf.WriteUint32(uint32(info.End.Unix()))
|
||||||
|
data = append(data, bf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doAckEarthSucceed(s, pkt.AckHandle, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfPostRyoudama(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgMhfPostRyoudama(s *Session, p mhfpacket.MHFPacket) {}
|
||||||
@@ -31,8 +83,41 @@ func handleMsgMhfPostTinyBin(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfCaravanMyScore(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgMhfCaravanMyScore(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
pkt := p.(*mhfpacket.MsgMhfCaravanMyScore)
|
||||||
|
var data []*byteframe.ByteFrame
|
||||||
|
/*
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
*/
|
||||||
|
doAckEarthSucceed(s, pkt.AckHandle, data)
|
||||||
|
}
|
||||||
|
|
||||||
func handleMsgMhfCaravanRanking(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgMhfCaravanRanking(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
pkt := p.(*mhfpacket.MsgMhfCaravanRanking)
|
||||||
|
var data []*byteframe.ByteFrame
|
||||||
|
/* RYOUDAN
|
||||||
|
bf.WriteInt32(1)
|
||||||
|
bf.WriteUint32(2)
|
||||||
|
bf.WriteBytes(stringsupport.PaddedString("Test", 26, true))
|
||||||
|
*/
|
||||||
|
|
||||||
func handleMsgMhfCaravanMyRank(s *Session, p mhfpacket.MHFPacket) {}
|
/* PERSONAL
|
||||||
|
bf.WriteInt32(1)
|
||||||
|
bf.WriteBytes(stringsupport.PaddedString("Test", 14, true))
|
||||||
|
*/
|
||||||
|
doAckEarthSucceed(s, pkt.AckHandle, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleMsgMhfCaravanMyRank(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
pkt := p.(*mhfpacket.MsgMhfCaravanMyRank)
|
||||||
|
var data []*byteframe.ByteFrame
|
||||||
|
/*
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
*/
|
||||||
|
doAckEarthSucceed(s, pkt.AckHandle, data)
|
||||||
|
}
|
||||||
|
|||||||
@@ -35,16 +35,16 @@ const (
|
|||||||
BroadcastTypeWorld = 0x0a
|
BroadcastTypeWorld = 0x0a
|
||||||
)
|
)
|
||||||
|
|
||||||
var commands map[string]config.Command
|
var commands map[string]_config.Command
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
commands = make(map[string]config.Command)
|
commands = make(map[string]_config.Command)
|
||||||
zapConfig := zap.NewDevelopmentConfig()
|
zapConfig := zap.NewDevelopmentConfig()
|
||||||
zapConfig.DisableCaller = true
|
zapConfig.DisableCaller = true
|
||||||
zapLogger, _ := zapConfig.Build()
|
zapLogger, _ := zapConfig.Build()
|
||||||
defer zapLogger.Sync()
|
defer zapLogger.Sync()
|
||||||
logger := zapLogger.Named("commands")
|
logger := zapLogger.Named("commands")
|
||||||
cmds := config.ErupeConfig.Commands
|
cmds := _config.ErupeConfig.Commands
|
||||||
for _, cmd := range cmds {
|
for _, cmd := range cmds {
|
||||||
commands[cmd.Name] = cmd
|
commands[cmd.Name] = cmd
|
||||||
if cmd.Enabled {
|
if cmd.Enabled {
|
||||||
@@ -55,7 +55,7 @@ func init() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendDisabledCommandMessage(s *Session, cmd config.Command) {
|
func sendDisabledCommandMessage(s *Session, cmd _config.Command) {
|
||||||
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandDisabled"], cmd.Name))
|
sendServerChatMessage(s, fmt.Sprintf(s.server.dict["commandDisabled"], cmd.Name))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,7 +211,7 @@ func parseChatCommand(s *Session, command string) {
|
|||||||
for _, course := range mhfcourse.Courses() {
|
for _, course := range mhfcourse.Courses() {
|
||||||
for _, alias := range course.Aliases() {
|
for _, alias := range course.Aliases() {
|
||||||
if strings.ToLower(name) == strings.ToLower(alias) {
|
if strings.ToLower(name) == strings.ToLower(alias) {
|
||||||
if slices.Contains(s.server.erupeConfig.Courses, config.Course{Name: course.Aliases()[0], Enabled: true}) {
|
if slices.Contains(s.server.erupeConfig.Courses, _config.Course{Name: course.Aliases()[0], Enabled: true}) {
|
||||||
var delta, rightsInt uint32
|
var delta, rightsInt uint32
|
||||||
if mhfcourse.CourseExists(course.ID, s.courses) {
|
if mhfcourse.CourseExists(course.ID, s.courses) {
|
||||||
ei := slices.IndexFunc(s.courses, func(c mhfcourse.Course) bool {
|
ei := slices.IndexFunc(s.courses, func(c mhfcourse.Course) bool {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"erupe-ce/common/bfutil"
|
"erupe-ce/common/bfutil"
|
||||||
"erupe-ce/common/stringsupport"
|
"erupe-ce/common/stringsupport"
|
||||||
|
_config "erupe-ce/config"
|
||||||
|
|
||||||
"erupe-ce/network/mhfpacket"
|
"erupe-ce/network/mhfpacket"
|
||||||
"erupe-ce/server/channelserver/compression/nullcomp"
|
"erupe-ce/server/channelserver/compression/nullcomp"
|
||||||
@@ -12,7 +13,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
pointerGender = 0x51 // +1
|
pointerGender = 0x51 // +1
|
||||||
|
|
||||||
pointerRP = 0x22D16 // +2
|
pointerRP = 0x22D16 // +2
|
||||||
pointerHouseTier = 0x1FB6C // +5
|
pointerHouseTier = 0x1FB6C // +5
|
||||||
pointerHouseData = 0x1FE01 // +195
|
pointerHouseData = 0x1FE01 // +195
|
||||||
@@ -26,6 +28,19 @@ const (
|
|||||||
pointerHRP = 0x1FDF6 // +2
|
pointerHRP = 0x1FDF6 // +2
|
||||||
pointerGRP = 0x1FDFC // +4
|
pointerGRP = 0x1FDFC // +4
|
||||||
pointerKQF = 0x23D20 // +8
|
pointerKQF = 0x23D20 // +8
|
||||||
|
|
||||||
|
pointerRPZ = 0x1A076
|
||||||
|
pointerHouseTierZ = 0x16ECC
|
||||||
|
pointerHouseDataZ = 0x17161
|
||||||
|
pointerBookshelfDataZ = 0x195F8
|
||||||
|
pointerGalleryDataZ = 0x19680
|
||||||
|
pointerToreDataZ = 0x17014
|
||||||
|
pointerGardenDataZ = 0x19FB8
|
||||||
|
pointerWeaponTypeZ = 0x16A75
|
||||||
|
pointerWeaponIDZ = 0x1696A
|
||||||
|
pointerHRPZ = 0x17156
|
||||||
|
pointerGRPZ = 0x1715C
|
||||||
|
pointerKQFZ = 0x1B080
|
||||||
)
|
)
|
||||||
|
|
||||||
type CharacterSaveData struct {
|
type CharacterSaveData struct {
|
||||||
@@ -81,10 +96,6 @@ func GetCharacterSaveData(s *Session, charID uint32) (*CharacterSaveData, error)
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(saveData.decompSave) < pointerKQF {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
saveData.updateStructWithSaveData()
|
saveData.updateStructWithSaveData()
|
||||||
|
|
||||||
return saveData, nil
|
return saveData, nil
|
||||||
@@ -137,8 +148,13 @@ func (save *CharacterSaveData) Decompress() error {
|
|||||||
func (save *CharacterSaveData) updateSaveDataWithStruct() {
|
func (save *CharacterSaveData) updateSaveDataWithStruct() {
|
||||||
rpBytes := make([]byte, 2)
|
rpBytes := make([]byte, 2)
|
||||||
binary.LittleEndian.PutUint16(rpBytes, save.RP)
|
binary.LittleEndian.PutUint16(rpBytes, save.RP)
|
||||||
copy(save.decompSave[pointerRP:pointerRP+2], rpBytes)
|
if _config.ErupeConfig.ClientMode == _config.ZZ {
|
||||||
copy(save.decompSave[pointerKQF:pointerKQF+8], save.KQF)
|
copy(save.decompSave[pointerRP:pointerRP+2], rpBytes)
|
||||||
|
copy(save.decompSave[pointerKQF:pointerKQF+8], save.KQF)
|
||||||
|
} else {
|
||||||
|
copy(save.decompSave[pointerRPZ:pointerRPZ+2], rpBytes)
|
||||||
|
copy(save.decompSave[pointerKQFZ:pointerKQFZ+8], save.KQF)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This will update the save struct with the values stored in the character save
|
// This will update the save struct with the values stored in the character save
|
||||||
@@ -150,20 +166,37 @@ func (save *CharacterSaveData) updateStructWithSaveData() {
|
|||||||
save.Gender = false
|
save.Gender = false
|
||||||
}
|
}
|
||||||
if !save.IsNewCharacter {
|
if !save.IsNewCharacter {
|
||||||
save.RP = binary.LittleEndian.Uint16(save.decompSave[pointerRP : pointerRP+2])
|
if _config.ErupeConfig.ClientMode == _config.ZZ {
|
||||||
save.HouseTier = save.decompSave[pointerHouseTier : pointerHouseTier+5]
|
save.RP = binary.LittleEndian.Uint16(save.decompSave[pointerRP : pointerRP+2])
|
||||||
save.HouseData = save.decompSave[pointerHouseData : pointerHouseData+195]
|
save.HouseTier = save.decompSave[pointerHouseTier : pointerHouseTier+5]
|
||||||
save.BookshelfData = save.decompSave[pointerBookshelfData : pointerBookshelfData+5576]
|
save.HouseData = save.decompSave[pointerHouseData : pointerHouseData+195]
|
||||||
save.GalleryData = save.decompSave[pointerGalleryData : pointerGalleryData+1748]
|
save.BookshelfData = save.decompSave[pointerBookshelfData : pointerBookshelfData+5576]
|
||||||
save.ToreData = save.decompSave[pointerToreData : pointerToreData+240]
|
save.GalleryData = save.decompSave[pointerGalleryData : pointerGalleryData+1748]
|
||||||
save.GardenData = save.decompSave[pointerGardenData : pointerGardenData+68]
|
save.ToreData = save.decompSave[pointerToreData : pointerToreData+240]
|
||||||
save.WeaponType = save.decompSave[pointerWeaponType]
|
save.GardenData = save.decompSave[pointerGardenData : pointerGardenData+68]
|
||||||
save.WeaponID = binary.LittleEndian.Uint16(save.decompSave[pointerWeaponID : pointerWeaponID+2])
|
save.WeaponType = save.decompSave[pointerWeaponType]
|
||||||
save.HRP = binary.LittleEndian.Uint16(save.decompSave[pointerHRP : pointerHRP+2])
|
save.WeaponID = binary.LittleEndian.Uint16(save.decompSave[pointerWeaponID : pointerWeaponID+2])
|
||||||
if save.HRP == uint16(999) {
|
save.HRP = binary.LittleEndian.Uint16(save.decompSave[pointerHRP : pointerHRP+2])
|
||||||
save.GR = grpToGR(binary.LittleEndian.Uint32(save.decompSave[pointerGRP : pointerGRP+4]))
|
if save.HRP == uint16(999) {
|
||||||
|
save.GR = grpToGR(binary.LittleEndian.Uint32(save.decompSave[pointerGRP : pointerGRP+4]))
|
||||||
|
}
|
||||||
|
save.KQF = save.decompSave[pointerKQF : pointerKQF+8]
|
||||||
|
} else {
|
||||||
|
save.RP = binary.LittleEndian.Uint16(save.decompSave[pointerRPZ : pointerRPZ+2])
|
||||||
|
save.HouseTier = save.decompSave[pointerHouseTierZ : pointerHouseTierZ+5]
|
||||||
|
save.HouseData = save.decompSave[pointerHouseDataZ : pointerHouseDataZ+195]
|
||||||
|
save.BookshelfData = save.decompSave[pointerBookshelfDataZ : pointerBookshelfDataZ+5576]
|
||||||
|
save.GalleryData = save.decompSave[pointerGalleryDataZ : pointerGalleryDataZ+1748]
|
||||||
|
save.ToreData = save.decompSave[pointerToreDataZ : pointerToreDataZ+240]
|
||||||
|
save.GardenData = save.decompSave[pointerGardenDataZ : pointerGardenDataZ+68]
|
||||||
|
save.WeaponType = save.decompSave[pointerWeaponTypeZ]
|
||||||
|
save.WeaponID = binary.LittleEndian.Uint16(save.decompSave[pointerWeaponIDZ : pointerWeaponIDZ+2])
|
||||||
|
save.HRP = binary.LittleEndian.Uint16(save.decompSave[pointerHRPZ : pointerHRPZ+2])
|
||||||
|
if save.HRP == uint16(999) {
|
||||||
|
save.GR = grpToGR(binary.LittleEndian.Uint32(save.decompSave[pointerGRPZ : pointerGRPZ+4]))
|
||||||
|
}
|
||||||
|
save.KQF = save.decompSave[pointerKQFZ : pointerKQFZ+8]
|
||||||
}
|
}
|
||||||
save.KQF = save.decompSave[pointerKQF : pointerKQF+8]
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -3,6 +3,7 @@ package channelserver
|
|||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"erupe-ce/common/stringsupport"
|
"erupe-ce/common/stringsupport"
|
||||||
|
_config "erupe-ce/config"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
@@ -71,7 +72,11 @@ func handleMsgMhfGetUdSchedule(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
var timestamps []uint32
|
var timestamps []uint32
|
||||||
if s.server.erupeConfig.DevMode && s.server.erupeConfig.DevModeOptions.DivaEvent >= 0 {
|
if s.server.erupeConfig.DevMode && s.server.erupeConfig.DevModeOptions.DivaEvent >= 0 {
|
||||||
if s.server.erupeConfig.DevModeOptions.DivaEvent == 0 {
|
if s.server.erupeConfig.DevModeOptions.DivaEvent == 0 {
|
||||||
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 36))
|
if s.server.erupeConfig.ClientMode == _config.Z1 {
|
||||||
|
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 32))
|
||||||
|
} else {
|
||||||
|
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 36))
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
timestamps = generateDivaTimestamps(s, uint32(s.server.erupeConfig.DevModeOptions.DivaEvent), true)
|
timestamps = generateDivaTimestamps(s, uint32(s.server.erupeConfig.DevModeOptions.DivaEvent), true)
|
||||||
@@ -79,9 +84,11 @@ func handleMsgMhfGetUdSchedule(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
timestamps = generateDivaTimestamps(s, start, false)
|
timestamps = generateDivaTimestamps(s, start, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
bf.WriteUint32(id)
|
if s.server.erupeConfig.ClientMode != _config.Z1 {
|
||||||
for _, timestamp := range timestamps {
|
bf.WriteUint32(id)
|
||||||
bf.WriteUint32(timestamp)
|
}
|
||||||
|
for i := range timestamps {
|
||||||
|
bf.WriteUint32(timestamps[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
bf.WriteUint16(0x19) // Unk 00011001
|
bf.WriteUint16(0x19) // Unk 00011001
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package channelserver
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"erupe-ce/common/token"
|
"erupe-ce/common/token"
|
||||||
|
_config "erupe-ce/config"
|
||||||
"math"
|
"math"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -90,14 +91,18 @@ func handleMsgMhfGetWeeklySchedule(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func generateFeatureWeapons(count int) activeFeature {
|
func generateFeatureWeapons(count int) activeFeature {
|
||||||
if count > 14 {
|
max := 14
|
||||||
count = 14
|
if _config.ErupeConfig.ClientMode != _config.ZZ {
|
||||||
|
max = 13
|
||||||
|
}
|
||||||
|
if count > max {
|
||||||
|
count = max
|
||||||
}
|
}
|
||||||
nums := make([]int, 0)
|
nums := make([]int, 0)
|
||||||
var result int
|
var result int
|
||||||
for len(nums) < count {
|
for len(nums) < count {
|
||||||
rng := token.RNG()
|
rng := token.RNG()
|
||||||
num := rng.Intn(14)
|
num := rng.Intn(max)
|
||||||
exist := false
|
exist := false
|
||||||
for _, v := range nums {
|
for _, v := range nums {
|
||||||
if v == num {
|
if v == num {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
_config "erupe-ce/config"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"sort"
|
"sort"
|
||||||
@@ -1390,7 +1391,12 @@ func handleMsgMhfEnumerateGuildMember(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
bf.WriteUint32(member.CharID)
|
bf.WriteUint32(member.CharID)
|
||||||
bf.WriteUint16(member.HRP)
|
bf.WriteUint16(member.HRP)
|
||||||
bf.WriteUint16(member.GR)
|
bf.WriteUint16(member.GR)
|
||||||
bf.WriteUint16(member.WeaponID)
|
if s.server.erupeConfig.ClientMode != _config.ZZ {
|
||||||
|
// Magnet Spike crash workaround
|
||||||
|
bf.WriteUint16(0)
|
||||||
|
} else {
|
||||||
|
bf.WriteUint16(member.WeaponID)
|
||||||
|
}
|
||||||
if member.WeaponType == 1 || member.WeaponType == 5 || member.WeaponType == 10 { // If weapon is ranged
|
if member.WeaponType == 1 || member.WeaponType == 5 || member.WeaponType == 10 { // If weapon is ranged
|
||||||
bf.WriteUint8(7)
|
bf.WriteUint8(7)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -222,8 +222,8 @@ func handleMsgMhfReadMercenaryM(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
func handleMsgMhfContractMercenary(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfContractMercenary(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfContractMercenary)
|
pkt := p.(*mhfpacket.MsgMhfContractMercenary)
|
||||||
switch pkt.Op {
|
switch pkt.Op {
|
||||||
case 0:
|
case 0: // Form loan
|
||||||
s.server.db.Exec("UPDATE characters SET pact_id=$1 WHERE id=$2", pkt.PactMercID, s.charID)
|
s.server.db.Exec("UPDATE characters SET pact_id=$1 WHERE id=$2", pkt.PactMercID, pkt.CID)
|
||||||
case 1: // Cancel lend
|
case 1: // Cancel lend
|
||||||
s.server.db.Exec("UPDATE characters SET pact_id=0 WHERE id=$1", s.charID)
|
s.server.db.Exec("UPDATE characters SET pact_id=0 WHERE id=$1", s.charID)
|
||||||
case 2: // Cancel loan
|
case 2: // Cancel loan
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
98
server/channelserver/handlers_seibattle.go
Normal file
98
server/channelserver/handlers_seibattle.go
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
package channelserver
|
||||||
|
|
||||||
|
import (
|
||||||
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network/mhfpacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
func handleMsgMhfGetBreakSeibatuLevelReward(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
pkt := p.(*mhfpacket.MsgMhfGetBreakSeibatuLevelReward)
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||||
|
}
|
||||||
|
|
||||||
|
type WeeklySeibatuRankingReward struct {
|
||||||
|
Unk0 int32
|
||||||
|
Unk1 int32
|
||||||
|
Unk2 uint32
|
||||||
|
Unk3 int32
|
||||||
|
Unk4 int32
|
||||||
|
Unk5 int32
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleMsgMhfGetWeeklySeibatuRankingReward(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
pkt := p.(*mhfpacket.MsgMhfGetWeeklySeibatuRankingReward)
|
||||||
|
var data []*byteframe.ByteFrame
|
||||||
|
weeklySeibatuRankingRewards := []WeeklySeibatuRankingReward{
|
||||||
|
{0, 0, 0, 0, 0, 0},
|
||||||
|
}
|
||||||
|
for _, reward := range weeklySeibatuRankingRewards {
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteInt32(reward.Unk0)
|
||||||
|
bf.WriteInt32(reward.Unk1)
|
||||||
|
bf.WriteUint32(reward.Unk2)
|
||||||
|
bf.WriteInt32(reward.Unk3)
|
||||||
|
bf.WriteInt32(reward.Unk4)
|
||||||
|
bf.WriteInt32(reward.Unk5)
|
||||||
|
data = append(data, bf)
|
||||||
|
}
|
||||||
|
doAckEarthSucceed(s, pkt.AckHandle, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleMsgMhfGetFixedSeibatuRankingTable(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
pkt := p.(*mhfpacket.MsgMhfGetFixedSeibatuRankingTable)
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
bf.WriteBytes(make([]byte, 32))
|
||||||
|
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleMsgMhfReadBeatLevel(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
pkt := p.(*mhfpacket.MsgMhfReadBeatLevel)
|
||||||
|
|
||||||
|
// This response is fixed and will never change on JP,
|
||||||
|
// but I've left it dynamic for possible other client differences.
|
||||||
|
resp := byteframe.NewByteFrame()
|
||||||
|
for i := 0; i < int(pkt.ValidIDCount); i++ {
|
||||||
|
resp.WriteUint32(pkt.IDs[i])
|
||||||
|
resp.WriteUint32(1)
|
||||||
|
resp.WriteUint32(1)
|
||||||
|
resp.WriteUint32(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleMsgMhfReadLastWeekBeatRanking(s *Session, p mhfpacket.MHFPacket) {}
|
||||||
|
|
||||||
|
func handleMsgMhfUpdateBeatLevel(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
pkt := p.(*mhfpacket.MsgMhfUpdateBeatLevel)
|
||||||
|
|
||||||
|
doAckBufSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleMsgMhfReadBeatLevelAllRanking(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
pkt := p.(*mhfpacket.MsgMhfReadBeatLevelAllRanking)
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteUint32(0)
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
bf.WriteUint32(0)
|
||||||
|
bf.WriteUint32(0)
|
||||||
|
bf.WriteBytes(make([]byte, 32))
|
||||||
|
}
|
||||||
|
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleMsgMhfReadBeatLevelMyRanking(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
pkt := p.(*mhfpacket.MsgMhfReadBeatLevelMyRanking)
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||||
|
}
|
||||||
@@ -1,102 +1,477 @@
|
|||||||
package channelserver
|
package channelserver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/hex"
|
"fmt"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/common/stringsupport"
|
||||||
"erupe-ce/network/mhfpacket"
|
"erupe-ce/network/mhfpacket"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type TowerInfoTRP struct {
|
||||||
|
TR int32
|
||||||
|
TRP int32
|
||||||
|
}
|
||||||
|
|
||||||
|
type TowerInfoSkill struct {
|
||||||
|
TSP int32
|
||||||
|
Unk1 []int16 // 40
|
||||||
|
}
|
||||||
|
|
||||||
|
type TowerInfoHistory struct {
|
||||||
|
Unk0 []int16 // 5
|
||||||
|
Unk1 []int16 // 5
|
||||||
|
}
|
||||||
|
|
||||||
|
type TowerInfoLevel struct {
|
||||||
|
Floors int32
|
||||||
|
Unk1 int32
|
||||||
|
Unk2 int32
|
||||||
|
Unk3 int32
|
||||||
|
}
|
||||||
|
|
||||||
func handleMsgMhfGetTowerInfo(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfGetTowerInfo(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfGetTowerInfo)
|
pkt := p.(*mhfpacket.MsgMhfGetTowerInfo)
|
||||||
var data []byte
|
var data []*byteframe.ByteFrame
|
||||||
var err error
|
type TowerInfo struct {
|
||||||
/*
|
TRP []TowerInfoTRP
|
||||||
type:
|
Skill []TowerInfoSkill
|
||||||
1 == TOWER_RANK_POINT,
|
History []TowerInfoHistory
|
||||||
2 == GET_OWN_TOWER_SKILL
|
Level []TowerInfoLevel
|
||||||
3 == GET_OWN_TOWER_LEVEL_V3
|
|
||||||
4 == TOWER_TOUHA_HISTORY
|
|
||||||
5 = ?
|
|
||||||
|
|
||||||
[] = type
|
|
||||||
req
|
|
||||||
resp
|
|
||||||
|
|
||||||
01 1d 01 fc 00 09 [00 00 00 01] 00 00 00 02 00 00 00 00
|
|
||||||
00 12 01 fc 00 09 01 00 00 18 0a 21 8e ad 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00
|
|
||||||
|
|
||||||
01 1d 01 fc 00 0a [00 00 00 02] 00 00 00 00 00 00 00 00
|
|
||||||
00 12 01 fc 00 0a 01 00 00 94 0a 21 8e ad 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
|
||||||
|
|
||||||
01 1d 01 ff 00 0f [00 00 00 04] 00 00 00 00 00 00 00 00
|
|
||||||
00 12 01 ff 00 0f 01 00 00 24 0a 21 8e ad 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
|
||||||
|
|
||||||
01 1d 01 fc 00 0b [00 00 00 05] 00 00 00 00 00 00 00 00
|
|
||||||
00 12 01 fc 00 0b 01 00 00 10 0a 21 8e ad 00 00 00 00 00 00 00 00 00 00 00 00
|
|
||||||
*/
|
|
||||||
switch pkt.InfoType {
|
|
||||||
case mhfpacket.TowerInfoTypeTowerRankPoint:
|
|
||||||
data, err = hex.DecodeString("0A218EAD0000000000000000000000010000000000000000")
|
|
||||||
case mhfpacket.TowerInfoTypeGetOwnTowerSkill:
|
|
||||||
//data, err = hex.DecodeString("0A218EAD000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
|
|
||||||
data, err = hex.DecodeString("0A218EAD0000000000000000000000010000001C0000000500050000000000020000000000000000000000000000000000030003000000000003000500050000000300030003000300030003000200030001000300020002000300010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000")
|
|
||||||
case mhfpacket.TowerInfoTypeGetOwnTowerLevelV3:
|
|
||||||
panic("No known response values for GetOwnTowerLevelV3")
|
|
||||||
case mhfpacket.TowerInfoTypeTowerTouhaHistory:
|
|
||||||
data, err = hex.DecodeString("0A218EAD0000000000000000000000010000000000000000000000000000000000000000")
|
|
||||||
case mhfpacket.TowerInfoTypeUnk5:
|
|
||||||
data, err = hex.DecodeString("0A218EAD000000000000000000000000")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
towerInfo := TowerInfo{
|
||||||
|
TRP: []TowerInfoTRP{{0, 0}},
|
||||||
|
Skill: []TowerInfoSkill{{0, make([]int16, 40)}},
|
||||||
|
History: []TowerInfoHistory{{make([]int16, 5), make([]int16, 5)}},
|
||||||
|
Level: []TowerInfoLevel{{0, 0, 0, 0}, {0, 0, 0, 0}},
|
||||||
|
}
|
||||||
|
|
||||||
|
tempSkills := "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
|
||||||
|
|
||||||
|
err := s.server.db.QueryRow(`SELECT COALESCE(tr, 0), COALESCE(trp, 0), COALESCE(tsp, 0), COALESCE(block1, 0), COALESCE(block2, 0), skills FROM tower WHERE char_id=$1
|
||||||
|
`, s.charID).Scan(&towerInfo.TRP[0].TR, &towerInfo.TRP[0].TRP, &towerInfo.Skill[0].TSP, &towerInfo.Level[0].Floors, &towerInfo.Level[1].Floors, &tempSkills)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
stubGetNoResults(s, pkt.AckHandle)
|
s.server.db.Exec(`INSERT INTO tower (char_id) VALUES ($1)`, s.charID)
|
||||||
}
|
}
|
||||||
doAckBufSucceed(s, pkt.AckHandle, data)
|
|
||||||
|
for i, skill := range stringsupport.CSVElems(tempSkills) {
|
||||||
|
towerInfo.Skill[0].Unk1[i] = int16(skill)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch pkt.InfoType {
|
||||||
|
case 1:
|
||||||
|
for _, trp := range towerInfo.TRP {
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteInt32(trp.TR)
|
||||||
|
bf.WriteInt32(trp.TRP)
|
||||||
|
data = append(data, bf)
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
for _, skills := range towerInfo.Skill {
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteInt32(skills.TSP)
|
||||||
|
for i := range skills.Unk1 {
|
||||||
|
bf.WriteInt16(skills.Unk1[i])
|
||||||
|
}
|
||||||
|
data = append(data, bf)
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
for _, history := range towerInfo.History {
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
for i := range history.Unk0 {
|
||||||
|
bf.WriteInt16(history.Unk0[i])
|
||||||
|
}
|
||||||
|
for i := range history.Unk1 {
|
||||||
|
bf.WriteInt16(history.Unk1[i])
|
||||||
|
}
|
||||||
|
data = append(data, bf)
|
||||||
|
}
|
||||||
|
case 5:
|
||||||
|
for _, level := range towerInfo.Level {
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteInt32(level.Floors)
|
||||||
|
bf.WriteInt32(level.Unk1)
|
||||||
|
bf.WriteInt32(level.Unk2)
|
||||||
|
bf.WriteInt32(level.Unk3)
|
||||||
|
data = append(data, bf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doAckEarthSucceed(s, pkt.AckHandle, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfPostTowerInfo(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfPostTowerInfo(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfPostTowerInfo)
|
pkt := p.(*mhfpacket.MsgMhfPostTowerInfo)
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
|
||||||
|
if s.server.erupeConfig.DevModeOptions.QuestDebugTools {
|
||||||
|
s.logger.Debug(
|
||||||
|
p.Opcode().String(),
|
||||||
|
zap.Uint32("InfoType", pkt.InfoType),
|
||||||
|
zap.Uint32("Unk1", pkt.Unk1),
|
||||||
|
zap.Int32("Skill", pkt.Skill),
|
||||||
|
zap.Int32("TR", pkt.TR),
|
||||||
|
zap.Int32("TRP", pkt.TRP),
|
||||||
|
zap.Int32("Cost", pkt.Cost),
|
||||||
|
zap.Int32("Unk6", pkt.Unk6),
|
||||||
|
zap.Int32("Unk7", pkt.Unk7),
|
||||||
|
zap.Int32("Block1", pkt.Block1),
|
||||||
|
zap.Int64("Unk9", pkt.Unk9),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch pkt.InfoType {
|
||||||
|
case 2:
|
||||||
|
skills := "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
|
||||||
|
s.server.db.QueryRow(`SELECT skills FROM tower WHERE char_id=$1`, s.charID).Scan(&skills)
|
||||||
|
s.server.db.Exec(`UPDATE tower SET skills=$1, tsp=tsp-$2 WHERE char_id=$3`, stringsupport.CSVSetIndex(skills, int(pkt.Skill), stringsupport.CSVGetIndex(skills, int(pkt.Skill))+1), pkt.Cost, s.charID)
|
||||||
|
case 7:
|
||||||
|
s.server.db.Exec(`UPDATE tower SET tr=$1, trp=trp+$2, block1=block1+$3 WHERE char_id=$4`, pkt.TR, pkt.TRP, pkt.Block1, s.charID)
|
||||||
|
}
|
||||||
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default missions
|
||||||
|
var tenrouiraiData = []TenrouiraiData{
|
||||||
|
{1, 1, 80, 0, 2, 2, 1, 1, 2, 2},
|
||||||
|
{1, 4, 16, 0, 2, 2, 1, 1, 2, 2},
|
||||||
|
{1, 6, 50, 0, 2, 2, 1, 0, 2, 2},
|
||||||
|
{1, 4, 12, 50, 2, 2, 1, 1, 2, 2},
|
||||||
|
{1, 3, 50, 0, 2, 2, 1, 1, 2, 2},
|
||||||
|
{2, 5, 40000, 0, 2, 2, 1, 0, 2, 2},
|
||||||
|
{1, 5, 50000, 50, 2, 2, 1, 1, 2, 2},
|
||||||
|
{2, 1, 60, 0, 2, 2, 1, 1, 2, 2},
|
||||||
|
{2, 3, 50, 0, 2, 1, 1, 0, 1, 2},
|
||||||
|
{2, 3, 40, 50, 2, 1, 1, 1, 1, 2},
|
||||||
|
{2, 4, 12, 0, 2, 1, 1, 1, 1, 2},
|
||||||
|
{2, 6, 40, 0, 2, 1, 1, 0, 1, 2},
|
||||||
|
{1, 1, 60, 50, 2, 1, 2, 1, 1, 2},
|
||||||
|
{1, 5, 50000, 0, 3, 1, 2, 1, 1, 2},
|
||||||
|
{1, 6, 50, 0, 3, 1, 2, 0, 1, 2},
|
||||||
|
{1, 4, 16, 50, 3, 1, 2, 1, 1, 2},
|
||||||
|
{1, 5, 50000, 0, 3, 1, 2, 1, 1, 2},
|
||||||
|
{2, 3, 40, 0, 3, 1, 2, 0, 1, 2},
|
||||||
|
{1, 3, 50, 50, 3, 1, 2, 1, 1, 2},
|
||||||
|
{2, 5, 40000, 0, 3, 1, 2, 1, 1, 1},
|
||||||
|
{2, 6, 40, 0, 3, 1, 2, 0, 1, 1},
|
||||||
|
{2, 1, 60, 50, 3, 1, 2, 1, 1, 1},
|
||||||
|
{2, 6, 50, 0, 3, 1, 2, 1, 1, 1},
|
||||||
|
{2, 4, 12, 0, 3, 1, 2, 0, 1, 1},
|
||||||
|
{1, 1, 80, 50, 3, 1, 2, 1, 1, 1},
|
||||||
|
{1, 5, 40000, 0, 3, 1, 2, 1, 1, 1},
|
||||||
|
{1, 3, 50, 0, 3, 1, 2, 0, 1, 1},
|
||||||
|
{1, 4, 16, 50, 3, 1, 0, 1, 1, 1},
|
||||||
|
{1, 6, 50, 0, 3, 1, 0, 1, 1, 1},
|
||||||
|
{2, 3, 40, 0, 3, 1, 0, 1, 1, 1},
|
||||||
|
{1, 1, 80, 50, 3, 1, 0, 0, 1, 1},
|
||||||
|
{2, 5, 40000, 0, 3, 1, 0, 0, 1, 1},
|
||||||
|
{2, 6, 40, 0, 3, 1, 0, 0, 1, 1},
|
||||||
|
}
|
||||||
|
|
||||||
|
type TenrouiraiProgress struct {
|
||||||
|
Page uint8
|
||||||
|
Mission1 uint16
|
||||||
|
Mission2 uint16
|
||||||
|
Mission3 uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
type TenrouiraiReward struct {
|
||||||
|
Index uint8
|
||||||
|
Item []uint16 // 5
|
||||||
|
Quantity []uint8 // 5
|
||||||
|
}
|
||||||
|
|
||||||
|
type TenrouiraiKeyScore struct {
|
||||||
|
Unk0 uint8
|
||||||
|
Unk1 int32
|
||||||
|
}
|
||||||
|
|
||||||
|
type TenrouiraiData struct {
|
||||||
|
Block uint8
|
||||||
|
Mission uint8
|
||||||
|
// 1 = Floors climbed
|
||||||
|
// 2 = Collect antiques
|
||||||
|
// 3 = Open chests
|
||||||
|
// 4 = Cats saved
|
||||||
|
// 5 = TRP acquisition
|
||||||
|
// 6 = Monster slays
|
||||||
|
Goal uint16
|
||||||
|
Cost uint16
|
||||||
|
Skill1 uint8 // 80
|
||||||
|
Skill2 uint8 // 40
|
||||||
|
Skill3 uint8 // 40
|
||||||
|
Skill4 uint8 // 20
|
||||||
|
Skill5 uint8 // 40
|
||||||
|
Skill6 uint8 // 50
|
||||||
|
}
|
||||||
|
|
||||||
|
type TenrouiraiCharScore struct {
|
||||||
|
Score int32
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
type TenrouiraiTicket struct {
|
||||||
|
Unk0 uint8
|
||||||
|
RP uint32
|
||||||
|
Unk2 uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type Tenrouirai struct {
|
||||||
|
Progress []TenrouiraiProgress
|
||||||
|
Reward []TenrouiraiReward
|
||||||
|
KeyScore []TenrouiraiKeyScore
|
||||||
|
Data []TenrouiraiData
|
||||||
|
CharScore []TenrouiraiCharScore
|
||||||
|
Ticket []TenrouiraiTicket
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfGetTenrouirai(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfGetTenrouirai(s *Session, p mhfpacket.MHFPacket) {
|
||||||
// if the game gets bad responses for this it breaks the ability to save
|
|
||||||
pkt := p.(*mhfpacket.MsgMhfGetTenrouirai)
|
pkt := p.(*mhfpacket.MsgMhfGetTenrouirai)
|
||||||
var data []byte
|
var data []*byteframe.ByteFrame
|
||||||
var err error
|
|
||||||
if pkt.Unk0 == 1 {
|
tenrouirai := Tenrouirai{
|
||||||
data, err = hex.DecodeString("0A218EAD000000000000000000000001010000000000060010")
|
Progress: []TenrouiraiProgress{{1, 0, 0, 0}},
|
||||||
} else if pkt.Unk2 == 4 {
|
Data: tenrouiraiData,
|
||||||
data, err = hex.DecodeString("0A218EAD0000000000000000000000210101005000000202010102020104001000000202010102020106003200000202010002020104000C003202020101020201030032000002020101020202059C4000000202010002020105C35000320202010102020201003C00000202010102020203003200000201010001020203002800320201010101020204000C00000201010101020206002800000201010001020101003C00320201020101020105C35000000301020101020106003200000301020001020104001000320301020101020105C350000003010201010202030028000003010200010201030032003203010201010202059C4000000301020101010206002800000301020001010201003C00320301020101010206003200000301020101010204000C000003010200010101010050003203010201010101059C40000003010201010101030032000003010200010101040010003203010001010101060032000003010001010102030028000003010001010101010050003203010000010102059C4000000301000001010206002800000301000001010010")
|
Ticket: []TenrouiraiTicket{{0, 0, 0}},
|
||||||
} else {
|
|
||||||
data = []byte{0x00, 0x00, 0x00, 0x00}
|
|
||||||
s.logger.Info("GET_TENROUIRAI request for unknown type")
|
|
||||||
}
|
}
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
switch pkt.Unk1 {
|
||||||
|
case 1:
|
||||||
|
for _, tdata := range tenrouirai.Data {
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteUint8(tdata.Block)
|
||||||
|
bf.WriteUint8(tdata.Mission)
|
||||||
|
bf.WriteUint16(tdata.Goal)
|
||||||
|
bf.WriteUint16(tdata.Cost)
|
||||||
|
bf.WriteUint8(tdata.Skill1)
|
||||||
|
bf.WriteUint8(tdata.Skill2)
|
||||||
|
bf.WriteUint8(tdata.Skill3)
|
||||||
|
bf.WriteUint8(tdata.Skill4)
|
||||||
|
bf.WriteUint8(tdata.Skill5)
|
||||||
|
bf.WriteUint8(tdata.Skill6)
|
||||||
|
data = append(data, bf)
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
for _, reward := range tenrouirai.Reward {
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteUint8(reward.Index)
|
||||||
|
bf.WriteUint16(reward.Item[0])
|
||||||
|
bf.WriteUint16(reward.Item[1])
|
||||||
|
bf.WriteUint16(reward.Item[2])
|
||||||
|
bf.WriteUint16(reward.Item[3])
|
||||||
|
bf.WriteUint16(reward.Item[4])
|
||||||
|
bf.WriteUint8(reward.Quantity[0])
|
||||||
|
bf.WriteUint8(reward.Quantity[1])
|
||||||
|
bf.WriteUint8(reward.Quantity[2])
|
||||||
|
bf.WriteUint8(reward.Quantity[3])
|
||||||
|
bf.WriteUint8(reward.Quantity[4])
|
||||||
|
data = append(data, bf)
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
s.server.db.QueryRow(`SELECT tower_mission_page FROM guilds WHERE id=$1`, pkt.GuildID).Scan(&tenrouirai.Progress[0].Page)
|
||||||
|
s.server.db.QueryRow(`SELECT SUM(tower_mission_1) AS _, SUM(tower_mission_2) AS _, SUM(tower_mission_3) AS _ FROM guild_characters WHERE guild_id=$1
|
||||||
|
`, pkt.GuildID).Scan(&tenrouirai.Progress[0].Mission1, &tenrouirai.Progress[0].Mission2, &tenrouirai.Progress[0].Mission3)
|
||||||
|
|
||||||
|
if tenrouirai.Progress[0].Mission1 > tenrouiraiData[(tenrouirai.Progress[0].Page*3)-3].Goal {
|
||||||
|
tenrouirai.Progress[0].Mission1 = tenrouiraiData[(tenrouirai.Progress[0].Page*3)-3].Goal
|
||||||
|
}
|
||||||
|
if tenrouirai.Progress[0].Mission2 > tenrouiraiData[(tenrouirai.Progress[0].Page*3)-2].Goal {
|
||||||
|
tenrouirai.Progress[0].Mission2 = tenrouiraiData[(tenrouirai.Progress[0].Page*3)-2].Goal
|
||||||
|
}
|
||||||
|
if tenrouirai.Progress[0].Mission3 > tenrouiraiData[(tenrouirai.Progress[0].Page*3)-1].Goal {
|
||||||
|
tenrouirai.Progress[0].Mission3 = tenrouiraiData[(tenrouirai.Progress[0].Page*3)-1].Goal
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, progress := range tenrouirai.Progress {
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteUint8(progress.Page)
|
||||||
|
bf.WriteUint16(progress.Mission1)
|
||||||
|
bf.WriteUint16(progress.Mission2)
|
||||||
|
bf.WriteUint16(progress.Mission3)
|
||||||
|
data = append(data, bf)
|
||||||
|
}
|
||||||
|
case 5:
|
||||||
|
if pkt.Unk3 > 3 {
|
||||||
|
pkt.Unk3 %= 3
|
||||||
|
if pkt.Unk3 == 0 {
|
||||||
|
pkt.Unk3 = 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rows, _ := s.server.db.Query(fmt.Sprintf(`SELECT name, tower_mission_%d FROM guild_characters gc INNER JOIN characters c ON gc.character_id = c.id WHERE guild_id=$1 AND tower_mission_%d IS NOT NULL ORDER BY tower_mission_%d DESC`, pkt.Unk3, pkt.Unk3, pkt.Unk3), pkt.GuildID)
|
||||||
|
for rows.Next() {
|
||||||
|
temp := TenrouiraiCharScore{}
|
||||||
|
rows.Scan(&temp.Name, &temp.Score)
|
||||||
|
tenrouirai.CharScore = append(tenrouirai.CharScore, temp)
|
||||||
|
}
|
||||||
|
for _, charScore := range tenrouirai.CharScore {
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteInt32(charScore.Score)
|
||||||
|
bf.WriteBytes(stringsupport.PaddedString(charScore.Name, 14, true))
|
||||||
|
data = append(data, bf)
|
||||||
|
}
|
||||||
|
case 6:
|
||||||
|
s.server.db.QueryRow(`SELECT tower_rp FROM guilds WHERE id=$1`, pkt.GuildID).Scan(&tenrouirai.Ticket[0].RP)
|
||||||
|
for _, ticket := range tenrouirai.Ticket {
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteUint8(ticket.Unk0)
|
||||||
|
bf.WriteUint32(ticket.RP)
|
||||||
|
bf.WriteUint32(ticket.Unk2)
|
||||||
|
data = append(data, bf)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
doAckBufSucceed(s, pkt.AckHandle, data)
|
|
||||||
|
doAckEarthSucceed(s, pkt.AckHandle, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfPostTenrouirai(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfPostTenrouirai(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfPostTenrouirai)
|
pkt := p.(*mhfpacket.MsgMhfPostTenrouirai)
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleMsgMhfGetBreakSeibatuLevelReward(s *Session, p mhfpacket.MHFPacket) {}
|
if s.server.erupeConfig.DevModeOptions.QuestDebugTools {
|
||||||
|
s.logger.Debug(
|
||||||
|
p.Opcode().String(),
|
||||||
|
zap.Uint8("Unk0", pkt.Unk0),
|
||||||
|
zap.Uint8("Op", pkt.Op),
|
||||||
|
zap.Uint32("GuildID", pkt.GuildID),
|
||||||
|
zap.Uint8("Unk1", pkt.Unk1),
|
||||||
|
zap.Uint16("Floors", pkt.Floors),
|
||||||
|
zap.Uint16("Antiques", pkt.Antiques),
|
||||||
|
zap.Uint16("Chests", pkt.Chests),
|
||||||
|
zap.Uint16("Cats", pkt.Cats),
|
||||||
|
zap.Uint16("TRP", pkt.TRP),
|
||||||
|
zap.Uint16("Slays", pkt.Slays),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
func handleMsgMhfGetWeeklySeibatuRankingReward(s *Session, p mhfpacket.MHFPacket) {
|
if pkt.Op == 2 {
|
||||||
pkt := p.(*mhfpacket.MsgMhfGetWeeklySeibatuRankingReward)
|
var page, requirement, donated int
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
s.server.db.QueryRow(`SELECT tower_mission_page, tower_rp FROM guilds WHERE id=$1`, pkt.GuildID).Scan(&page, &donated)
|
||||||
|
|
||||||
|
for i := 0; i < (page*3)+1; i++ {
|
||||||
|
requirement += int(tenrouiraiData[i].Cost)
|
||||||
|
}
|
||||||
|
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
|
||||||
|
sd, err := GetCharacterSaveData(s, s.charID)
|
||||||
|
if err == nil && sd != nil {
|
||||||
|
sd.RP -= pkt.DonatedRP
|
||||||
|
sd.Save(s)
|
||||||
|
if donated+int(pkt.DonatedRP) >= requirement {
|
||||||
|
s.server.db.Exec(`UPDATE guilds SET tower_mission_page=tower_mission_page+1 WHERE id=$1`, pkt.GuildID)
|
||||||
|
s.server.db.Exec(`UPDATE guild_characters SET tower_mission_1=NULL, tower_mission_2=NULL, tower_mission_3=NULL WHERE guild_id=$1`, pkt.GuildID)
|
||||||
|
pkt.DonatedRP = uint16(requirement - donated)
|
||||||
|
}
|
||||||
|
bf.WriteUint32(uint32(pkt.DonatedRP))
|
||||||
|
s.server.db.Exec(`UPDATE guilds SET tower_rp=tower_rp+$1 WHERE id=$2`, pkt.DonatedRP, pkt.GuildID)
|
||||||
|
} else {
|
||||||
|
bf.WriteUint32(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())
|
||||||
|
} else {
|
||||||
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfPresentBox(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfPresentBox(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfPresentBox)
|
pkt := p.(*mhfpacket.MsgMhfPresentBox)
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
var data []*byteframe.ByteFrame
|
||||||
|
/*
|
||||||
|
bf.WriteUint32(0)
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
bf.WriteInt32(0)
|
||||||
|
*/
|
||||||
|
doAckEarthSucceed(s, pkt.AckHandle, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
type GemInfo struct {
|
||||||
|
Gem uint16
|
||||||
|
Quantity uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
type GemHistory struct {
|
||||||
|
Gem uint16
|
||||||
|
Message uint16
|
||||||
|
Timestamp time.Time
|
||||||
|
Sender string
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfGetGemInfo(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfGetGemInfo(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfGetGemInfo)
|
pkt := p.(*mhfpacket.MsgMhfGetGemInfo)
|
||||||
|
var data []*byteframe.ByteFrame
|
||||||
|
gemInfo := []GemInfo{}
|
||||||
|
gemHistory := []GemHistory{}
|
||||||
|
|
||||||
|
tempGems := "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
|
||||||
|
s.server.db.QueryRow(`SELECT gems FROM tower WHERE char_id=$1`, s.charID).Scan(&tempGems)
|
||||||
|
for i, v := range stringsupport.CSVElems(tempGems) {
|
||||||
|
gemInfo = append(gemInfo, GemInfo{uint16(((i / 5) * 256) + ((i % 5) + 1)), uint16(v)})
|
||||||
|
}
|
||||||
|
|
||||||
|
switch pkt.Unk0 {
|
||||||
|
case 1:
|
||||||
|
for _, info := range gemInfo {
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteUint16(info.Gem)
|
||||||
|
bf.WriteUint16(info.Quantity)
|
||||||
|
data = append(data, bf)
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
for _, history := range gemHistory {
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteUint16(history.Gem)
|
||||||
|
bf.WriteUint16(history.Message)
|
||||||
|
bf.WriteUint32(uint32(history.Timestamp.Unix()))
|
||||||
|
bf.WriteBytes(stringsupport.PaddedString(history.Sender, 14, true))
|
||||||
|
data = append(data, bf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
doAckEarthSucceed(s, pkt.AckHandle, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleMsgMhfPostGemInfo(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
pkt := p.(*mhfpacket.MsgMhfPostGemInfo)
|
||||||
|
|
||||||
|
if s.server.erupeConfig.DevModeOptions.QuestDebugTools {
|
||||||
|
s.logger.Debug(
|
||||||
|
p.Opcode().String(),
|
||||||
|
zap.Uint32("Op", pkt.Op),
|
||||||
|
zap.Uint32("Unk1", pkt.Unk1),
|
||||||
|
zap.Int32("Gem", pkt.Gem),
|
||||||
|
zap.Int32("Quantity", pkt.Quantity),
|
||||||
|
zap.Int32("CID", pkt.CID),
|
||||||
|
zap.Int32("Message", pkt.Message),
|
||||||
|
zap.Int32("Unk6", pkt.Unk6),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
gems := "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0"
|
||||||
|
s.server.db.QueryRow(`SELECT gems FROM tower WHERE char_id=$1`, s.charID).Scan(&gems)
|
||||||
|
switch pkt.Op {
|
||||||
|
case 1: // Add gem
|
||||||
|
i := int(((pkt.Gem / 256) * 5) + (((pkt.Gem - ((pkt.Gem / 256) * 256)) - 1) % 5))
|
||||||
|
s.server.db.Exec(`UPDATE tower SET gems=$1 WHERE char_id=$2`, stringsupport.CSVSetIndex(gems, i, stringsupport.CSVGetIndex(gems, i)+int(pkt.Quantity)), s.charID)
|
||||||
|
case 2: // Transfer gem
|
||||||
|
// no way im doing this for now
|
||||||
|
}
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfPostGemInfo(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgMhfGetNotice(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
pkt := p.(*mhfpacket.MsgMhfGetNotice)
|
||||||
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleMsgMhfPostNotice(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
pkt := p.(*mhfpacket.MsgMhfPostNotice)
|
||||||
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ type Config struct {
|
|||||||
Logger *zap.Logger
|
Logger *zap.Logger
|
||||||
DB *sqlx.DB
|
DB *sqlx.DB
|
||||||
DiscordBot *discordbot.DiscordBot
|
DiscordBot *discordbot.DiscordBot
|
||||||
ErupeConfig *config.Config
|
ErupeConfig *_config.Config
|
||||||
Name string
|
Name string
|
||||||
Enable bool
|
Enable bool
|
||||||
}
|
}
|
||||||
@@ -43,7 +43,7 @@ type Server struct {
|
|||||||
Port uint16
|
Port uint16
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
db *sqlx.DB
|
db *sqlx.DB
|
||||||
erupeConfig *config.Config
|
erupeConfig *_config.Config
|
||||||
acceptConns chan net.Conn
|
acceptConns chan net.Conn
|
||||||
deleteConns chan net.Conn
|
deleteConns chan net.Conn
|
||||||
sessions map[net.Conn]*Session
|
sessions map[net.Conn]*Session
|
||||||
|
|||||||
@@ -9,14 +9,14 @@ import (
|
|||||||
|
|
||||||
type DiscordBot struct {
|
type DiscordBot struct {
|
||||||
Session *discordgo.Session
|
Session *discordgo.Session
|
||||||
config *config.Config
|
config *_config.Config
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
MainGuild *discordgo.Guild
|
MainGuild *discordgo.Guild
|
||||||
RealtimeChannel *discordgo.Channel
|
RealtimeChannel *discordgo.Channel
|
||||||
}
|
}
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
Config *config.Config
|
Config *_config.Config
|
||||||
Logger *zap.Logger
|
Logger *zap.Logger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import (
|
|||||||
type Server struct {
|
type Server struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
erupeConfig *config.Config
|
erupeConfig *_config.Config
|
||||||
db *sqlx.DB
|
db *sqlx.DB
|
||||||
listener net.Listener
|
listener net.Listener
|
||||||
isShuttingDown bool
|
isShuttingDown bool
|
||||||
@@ -28,7 +28,7 @@ type Server struct {
|
|||||||
type Config struct {
|
type Config struct {
|
||||||
Logger *zap.Logger
|
Logger *zap.Logger
|
||||||
DB *sqlx.DB
|
DB *sqlx.DB
|
||||||
ErupeConfig *config.Config
|
ErupeConfig *_config.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewServer creates a new Server type.
|
// NewServer creates a new Server type.
|
||||||
@@ -68,7 +68,7 @@ func (s *Server) Shutdown() {
|
|||||||
s.listener.Close()
|
s.listener.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
//acceptClients handles accepting new clients in a loop.
|
// acceptClients handles accepting new clients in a loop.
|
||||||
func (s *Server) acceptClients() {
|
func (s *Server) acceptClients() {
|
||||||
for {
|
for {
|
||||||
conn, err := s.listener.Accept()
|
conn, err := s.listener.Accept()
|
||||||
|
|||||||
@@ -3,13 +3,13 @@ package entranceserver
|
|||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
_config "erupe-ce/config"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"erupe-ce/common/stringsupport"
|
"erupe-ce/common/stringsupport"
|
||||||
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
"erupe-ce/config"
|
|
||||||
"erupe-ce/server/channelserver"
|
"erupe-ce/server/channelserver"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -19,11 +19,17 @@ var season uint8
|
|||||||
// Server Channels
|
// Server Channels
|
||||||
var currentplayers uint16
|
var currentplayers uint16
|
||||||
|
|
||||||
func encodeServerInfo(config *config.Config, s *Server, local bool) []byte {
|
func encodeServerInfo(config *_config.Config, s *Server, local bool) []byte {
|
||||||
serverInfos := config.Entrance.Entries
|
serverInfos := config.Entrance.Entries
|
||||||
bf := byteframe.NewByteFrame()
|
bf := byteframe.NewByteFrame()
|
||||||
|
|
||||||
for serverIdx, si := range serverInfos {
|
for serverIdx, si := range serverInfos {
|
||||||
|
// Prevent MezFes Worlds displaying on Z1
|
||||||
|
if config.ClientMode == _config.Z1 {
|
||||||
|
if si.Type == 6 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
sid := (4096 + serverIdx*256) + 16
|
sid := (4096 + serverIdx*256) + 16
|
||||||
err := s.db.QueryRow("SELECT season FROM servers WHERE server_id=$1", sid).Scan(&season)
|
err := s.db.QueryRow("SELECT season FROM servers WHERE server_id=$1", sid).Scan(&season)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -91,8 +97,17 @@ func makeHeader(data []byte, respType string, entryCount uint16, key byte) []byt
|
|||||||
return bf.Data()
|
return bf.Data()
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeSv2Resp(config *config.Config, s *Server, local bool) []byte {
|
func makeSv2Resp(config *_config.Config, s *Server, local bool) []byte {
|
||||||
serverInfos := config.Entrance.Entries
|
serverInfos := config.Entrance.Entries
|
||||||
|
// Decrease by the number of MezFes Worlds
|
||||||
|
var mf int
|
||||||
|
if config.ClientMode == _config.Z1 {
|
||||||
|
for _, si := range serverInfos {
|
||||||
|
if si.Type == 6 {
|
||||||
|
mf++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
rawServerData := encodeServerInfo(config, s, local)
|
rawServerData := encodeServerInfo(config, s, local)
|
||||||
|
|
||||||
if s.erupeConfig.DevMode && s.erupeConfig.DevModeOptions.LogOutboundMessages {
|
if s.erupeConfig.DevMode && s.erupeConfig.DevModeOptions.LogOutboundMessages {
|
||||||
@@ -100,7 +115,7 @@ func makeSv2Resp(config *config.Config, s *Server, local bool) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bf := byteframe.NewByteFrame()
|
bf := byteframe.NewByteFrame()
|
||||||
bf.WriteBytes(makeHeader(rawServerData, "SV2", uint16(len(serverInfos)), 0x00))
|
bf.WriteBytes(makeHeader(rawServerData, "SV2", uint16(len(serverInfos)-mf), 0x00))
|
||||||
return bf.Data()
|
return bf.Data()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,14 +16,14 @@ import (
|
|||||||
type Config struct {
|
type Config struct {
|
||||||
Logger *zap.Logger
|
Logger *zap.Logger
|
||||||
DB *sqlx.DB
|
DB *sqlx.DB
|
||||||
ErupeConfig *config.Config
|
ErupeConfig *_config.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
// Server is a MHF sign server.
|
// Server is a MHF sign server.
|
||||||
type Server struct {
|
type Server struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
erupeConfig *config.Config
|
erupeConfig *_config.Config
|
||||||
sessions map[int]*Session
|
sessions map[int]*Session
|
||||||
db *sqlx.DB
|
db *sqlx.DB
|
||||||
listener net.Listener
|
listener net.Listener
|
||||||
|
|||||||
@@ -18,14 +18,14 @@ import (
|
|||||||
type Config struct {
|
type Config struct {
|
||||||
Logger *zap.Logger
|
Logger *zap.Logger
|
||||||
DB *sqlx.DB
|
DB *sqlx.DB
|
||||||
ErupeConfig *config.Config
|
ErupeConfig *_config.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
// Server is the MHF custom launcher sign server.
|
// Server is the MHF custom launcher sign server.
|
||||||
type Server struct {
|
type Server struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
logger *zap.Logger
|
logger *zap.Logger
|
||||||
erupeConfig *config.Config
|
erupeConfig *_config.Config
|
||||||
db *sqlx.DB
|
db *sqlx.DB
|
||||||
httpServer *http.Server
|
httpServer *http.Server
|
||||||
isShuttingDown bool
|
isShuttingDown bool
|
||||||
|
|||||||
Reference in New Issue
Block a user