mirror of
https://github.com/Mezeporta/Erupe.git
synced 2025-12-15 00:15:08 +01:00
Merge branch 'main' into pr/sign-v2
This commit is contained in:
13
common/token/token.go
Normal file
13
common/token/token.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package token
|
||||||
|
|
||||||
|
import "math/rand"
|
||||||
|
|
||||||
|
// Generate returns an alphanumeric token of specified length
|
||||||
|
func Generate(length int) string {
|
||||||
|
var chars = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
|
||||||
|
b := make([]rune, length)
|
||||||
|
for i := range b {
|
||||||
|
b[i] = chars[rand.Intn(len(chars))]
|
||||||
|
}
|
||||||
|
return string(b)
|
||||||
|
}
|
||||||
@@ -3,13 +3,14 @@
|
|||||||
"BinPath": "bin",
|
"BinPath": "bin",
|
||||||
"DisableSoftCrash": false,
|
"DisableSoftCrash": false,
|
||||||
"FeaturedWeapons": 1,
|
"FeaturedWeapons": 1,
|
||||||
|
"HideLoginNotice": true,
|
||||||
|
"LoginNotice": "<BODY><CENTER><SIZE_3><C_4>Welcome to Erupe SU9.1!<BR><BODY><LEFT><SIZE_2><C_5>Erupe is experimental software<C_7>, we are not liable for any<BR><BODY>issues caused by installing the software!<BR><BODY><BR><BODY><C_4>■Report bugs on Discord!<C_7><BR><BODY><BR><BODY><C_4>■Test everything!<C_7><BR><BODY><BR><BODY><C_4>■Don't talk to softlocking NPCs!<C_7><BR><BODY><BR><BODY><C_4>■Fork the code on GitHub!<C_7><BR><BODY><BR><BODY>Thank you to all of the contributors,<BR><BODY><BR><BODY>this wouldn't exist without you.",
|
||||||
|
"PatchServerManifest": "",
|
||||||
|
"PatchServerFile": "",
|
||||||
|
"ScreenshotAPIURL": "",
|
||||||
"DevMode": true,
|
"DevMode": true,
|
||||||
"DevModeOptions": {
|
"DevModeOptions": {
|
||||||
"PatchServerManifest": "",
|
|
||||||
"PatchServerFile": "",
|
|
||||||
"AutoCreateAccount": true,
|
"AutoCreateAccount": true,
|
||||||
"HideLoginNotice": false,
|
|
||||||
"LoginNotice": "<BODY><CENTER><SIZE_3><C_4>Welcome to Erupe SU9.1!<BR><BODY><LEFT><SIZE_2><C_5>Erupe is experimental software<C_7>, we are not liable for any<BR><BODY>issues caused by installing the software!<BR><BODY><BR><BODY><C_4>■Report bugs on Discord!<C_7><BR><BODY><BR><BODY><C_4>■Test everything!<C_7><BR><BODY><BR><BODY><C_4>■Don't talk to softlocking NPCs!<C_7><BR><BODY><BR><BODY><C_4>■Fork the code on GitHub!<C_7><BR><BODY><BR><BODY>Thank you to all of the contributors,<BR><BODY><BR><BODY>this wouldn't exist without you.",
|
|
||||||
"CleanDB": false,
|
"CleanDB": false,
|
||||||
"MaxLauncherHR": false,
|
"MaxLauncherHR": false,
|
||||||
"LogInboundMessages": false,
|
"LogInboundMessages": false,
|
||||||
|
|||||||
@@ -12,11 +12,16 @@ import (
|
|||||||
|
|
||||||
// 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"`
|
||||||
BinPath string `mapstructure:"BinPath"`
|
BinPath string `mapstructure:"BinPath"`
|
||||||
DisableSoftCrash bool // Disables the 'Press Return to exit' dialog allowing scripts to reboot the server automatically
|
DisableSoftCrash bool // Disables the 'Press Return to exit' dialog allowing scripts to reboot the server automatically
|
||||||
FeaturedWeapons int // Number of Active Feature weapons to generate daily
|
FeaturedWeapons int // Number of Active Feature weapons to generate daily
|
||||||
DevMode bool
|
HideLoginNotice bool // Hide the Erupe notice on login
|
||||||
|
LoginNotice string // MHFML string of the login notice displayed
|
||||||
|
PatchServerManifest string // Manifest patch server override
|
||||||
|
PatchServerFile string // File patch server override
|
||||||
|
ScreenshotAPIURL string // Destination for screenshots uploaded to BBS
|
||||||
|
DevMode bool
|
||||||
|
|
||||||
DevModeOptions DevModeOptions
|
DevModeOptions DevModeOptions
|
||||||
Discord Discord
|
Discord Discord
|
||||||
@@ -32,24 +37,20 @@ 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 {
|
||||||
PatchServerManifest string // Manifest patch server override
|
AutoCreateAccount bool // Automatically create accounts if they don't exist
|
||||||
PatchServerFile string // File patch server override
|
CleanDB bool // Automatically wipes the DB on server reset.
|
||||||
AutoCreateAccount bool // Automatically create accounts if they don't exist
|
MaxLauncherHR bool // Sets the HR returned in the launcher to HR7 so that you can join non-beginner worlds.
|
||||||
HideLoginNotice bool // Hide the Erupe notice on login
|
LogInboundMessages bool // Log all messages sent to the server
|
||||||
LoginNotice string // MHFML string of the login notice displayed
|
LogOutboundMessages bool // Log all messages sent to the clients
|
||||||
CleanDB bool // Automatically wipes the DB on server reset.
|
MaxHexdumpLength int // Maximum number of bytes printed when logs are enabled
|
||||||
MaxLauncherHR bool // Sets the HR returned in the launcher to HR7 so that you can join non-beginner worlds.
|
DivaEvent int // Diva Defense event status
|
||||||
LogInboundMessages bool // Log all messages sent to the server
|
FestaEvent int // Hunter's Festa event status
|
||||||
LogOutboundMessages bool // Log all messages sent to the clients
|
TournamentEvent int // VS Tournament event status
|
||||||
MaxHexdumpLength int // Maximum number of bytes printed when logs are enabled
|
MezFesEvent bool // MezFes status
|
||||||
DivaEvent int // Diva Defense event status
|
MezFesAlt bool // Swaps out Volpakkun for Tokotoko
|
||||||
FestaEvent int // Hunter's Festa event status
|
DisableTokenCheck bool // Disables checking login token exists in the DB (security risk!)
|
||||||
TournamentEvent int // VS Tournament event status
|
DisableMailItems bool // Hack to prevent english versions of MHF from crashing
|
||||||
MezFesEvent bool // MezFes status
|
QuestDebugTools bool // Enable various quest debug logs
|
||||||
MezFesAlt bool // Swaps out Volpakkun for Tokotoko
|
|
||||||
DisableTokenCheck bool // Disables checking login token exists in the DB (security risk!)
|
|
||||||
DisableMailItems bool // Hack to prevent english versions of MHF from crashing
|
|
||||||
QuestDebugTools bool // Enable various quest debug logs
|
|
||||||
SaveDumps SaveDumpOptions
|
SaveDumps SaveDumpOptions
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,24 @@
|
|||||||
package mhfpacket
|
package mhfpacket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"erupe-ce/common/bfutil"
|
||||||
|
"erupe-ce/common/stringsupport"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfApplyBbsArticle represents the MSG_MHF_APPLY_BBS_ARTICLE
|
// MsgMhfApplyBbsArticle represents the MSG_MHF_APPLY_BBS_ARTICLE
|
||||||
type MsgMhfApplyBbsArticle struct{}
|
type MsgMhfApplyBbsArticle struct {
|
||||||
|
AckHandle uint32
|
||||||
|
Unk0 uint32
|
||||||
|
Unk1 []byte
|
||||||
|
Name string
|
||||||
|
Title string
|
||||||
|
Description string
|
||||||
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
func (m *MsgMhfApplyBbsArticle) Opcode() network.PacketID {
|
func (m *MsgMhfApplyBbsArticle) Opcode() network.PacketID {
|
||||||
@@ -18,7 +27,13 @@ func (m *MsgMhfApplyBbsArticle) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfApplyBbsArticle) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfApplyBbsArticle) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
return errors.New("NOT IMPLEMENTED")
|
m.AckHandle = bf.ReadUint32()
|
||||||
|
m.Unk0 = bf.ReadUint32()
|
||||||
|
m.Unk1 = bf.ReadBytes(16)
|
||||||
|
m.Name = stringsupport.SJISToUTF8(bfutil.UpToNull(bf.ReadBytes(32)))
|
||||||
|
m.Title = stringsupport.SJISToUTF8(bfutil.UpToNull(bf.ReadBytes(128)))
|
||||||
|
m.Description = stringsupport.SJISToUTF8(bfutil.UpToNull(bf.ReadBytes(256)))
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build builds a binary packet from the current data.
|
// Build builds a binary packet from the current data.
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
package mhfpacket
|
package mhfpacket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfGetBbsSnsStatus represents the MSG_MHF_GET_BBS_SNS_STATUS
|
// MsgMhfGetBbsSnsStatus represents the MSG_MHF_GET_BBS_SNS_STATUS
|
||||||
type MsgMhfGetBbsSnsStatus struct{}
|
type MsgMhfGetBbsSnsStatus struct {
|
||||||
|
AckHandle uint32
|
||||||
|
Unk []byte
|
||||||
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
func (m *MsgMhfGetBbsSnsStatus) Opcode() network.PacketID {
|
func (m *MsgMhfGetBbsSnsStatus) Opcode() network.PacketID {
|
||||||
@@ -18,7 +21,9 @@ func (m *MsgMhfGetBbsSnsStatus) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfGetBbsSnsStatus) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfGetBbsSnsStatus) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
return errors.New("NOT IMPLEMENTED")
|
m.AckHandle = bf.ReadUint32()
|
||||||
|
m.Unk = bf.ReadBytes(12)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build builds a binary packet from the current data.
|
// Build builds a binary packet from the current data.
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
package mhfpacket
|
package mhfpacket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"erupe-ce/network/clientctx"
|
|
||||||
"erupe-ce/network"
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/network"
|
||||||
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfGetBbsUserStatus represents the MSG_MHF_GET_BBS_USER_STATUS
|
// MsgMhfGetBbsUserStatus represents the MSG_MHF_GET_BBS_USER_STATUS
|
||||||
type MsgMhfGetBbsUserStatus struct{}
|
type MsgMhfGetBbsUserStatus struct {
|
||||||
|
AckHandle uint32
|
||||||
|
Unk []byte
|
||||||
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
func (m *MsgMhfGetBbsUserStatus) Opcode() network.PacketID {
|
func (m *MsgMhfGetBbsUserStatus) Opcode() network.PacketID {
|
||||||
@@ -18,7 +21,9 @@ func (m *MsgMhfGetBbsUserStatus) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfGetBbsUserStatus) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfGetBbsUserStatus) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
return errors.New("NOT IMPLEMENTED")
|
m.AckHandle = bf.ReadUint32()
|
||||||
|
m.Unk = bf.ReadBytes(12)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build builds a binary packet from the current data.
|
// Build builds a binary packet from the current data.
|
||||||
|
|||||||
@@ -1495,10 +1495,6 @@ func handleMsgMhfInfoScenarioCounter(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
doAckBufSucceed(s, pkt.AckHandle, resp.Data())
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgMhfGetBbsSnsStatus(s *Session, p mhfpacket.MHFPacket) {}
|
|
||||||
|
|
||||||
func handleMsgMhfApplyBbsArticle(s *Session, p mhfpacket.MHFPacket) {}
|
|
||||||
|
|
||||||
func handleMsgMhfGetEtcPoints(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgMhfGetEtcPoints(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgMhfGetEtcPoints)
|
pkt := p.(*mhfpacket.MsgMhfGetEtcPoints)
|
||||||
|
|
||||||
|
|||||||
41
server/channelserver/handlers_bbs.go
Normal file
41
server/channelserver/handlers_bbs.go
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package channelserver
|
||||||
|
|
||||||
|
import (
|
||||||
|
"erupe-ce/common/byteframe"
|
||||||
|
"erupe-ce/common/stringsupport"
|
||||||
|
"erupe-ce/common/token"
|
||||||
|
"erupe-ce/network/mhfpacket"
|
||||||
|
)
|
||||||
|
|
||||||
|
func handleMsgMhfGetBbsUserStatus(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
pkt := p.(*mhfpacket.MsgMhfGetBbsUserStatus)
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteUint32(200)
|
||||||
|
bf.WriteUint32(0)
|
||||||
|
bf.WriteUint32(0)
|
||||||
|
bf.WriteUint32(0)
|
||||||
|
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleMsgMhfGetBbsSnsStatus(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
pkt := p.(*mhfpacket.MsgMhfGetBbsSnsStatus)
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
bf.WriteUint32(200)
|
||||||
|
bf.WriteUint32(401)
|
||||||
|
bf.WriteUint32(401)
|
||||||
|
bf.WriteUint32(0)
|
||||||
|
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleMsgMhfApplyBbsArticle(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
pkt := p.(*mhfpacket.MsgMhfApplyBbsArticle)
|
||||||
|
bf := byteframe.NewByteFrame()
|
||||||
|
articleToken := token.Generate(40)
|
||||||
|
bf.WriteUint32(200)
|
||||||
|
bf.WriteUint32(80)
|
||||||
|
bf.WriteUint32(0)
|
||||||
|
bf.WriteUint32(0)
|
||||||
|
bf.WriteBytes(stringsupport.PaddedString(articleToken, 64, false))
|
||||||
|
bf.WriteBytes(stringsupport.PaddedString(s.server.erupeConfig.ScreenshotAPIURL, 64, false))
|
||||||
|
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||||
|
}
|
||||||
@@ -54,5 +54,3 @@ func handleMsgSysGetUserBinary(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgSysNotifyUserBinary(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgSysNotifyUserBinary(s *Session, p mhfpacket.MHFPacket) {}
|
||||||
|
|
||||||
func handleMsgMhfGetBbsUserStatus(s *Session, p mhfpacket.MHFPacket) {}
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
ps "erupe-ce/common/pascalstring"
|
ps "erupe-ce/common/pascalstring"
|
||||||
"erupe-ce/common/stringsupport"
|
"erupe-ce/common/stringsupport"
|
||||||
|
"erupe-ce/common/token"
|
||||||
"erupe-ce/server/channelserver"
|
"erupe-ce/server/channelserver"
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
@@ -18,15 +19,6 @@ func makeSignInFailureResp(respID RespID) []byte {
|
|||||||
return bf.Data()
|
return bf.Data()
|
||||||
}
|
}
|
||||||
|
|
||||||
func randSeq(n int) string {
|
|
||||||
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
|
||||||
b := make([]rune, n)
|
|
||||||
for i := range b {
|
|
||||||
b[i] = letters[rand.Intn(len(letters))]
|
|
||||||
}
|
|
||||||
return string(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Session) makeSignInResp(uid int) []byte {
|
func (s *Session) makeSignInResp(uid int) []byte {
|
||||||
returnExpiry := s.server.getReturnExpiry(uid)
|
returnExpiry := s.server.getReturnExpiry(uid)
|
||||||
|
|
||||||
@@ -37,13 +29,13 @@ func (s *Session) makeSignInResp(uid int) []byte {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rand.Seed(time.Now().UnixNano())
|
rand.Seed(time.Now().UnixNano())
|
||||||
token := randSeq(16)
|
sessToken := token.Generate(16)
|
||||||
s.server.registerToken(uid, token)
|
s.server.registerToken(uid, sessToken)
|
||||||
|
|
||||||
bf := byteframe.NewByteFrame()
|
bf := byteframe.NewByteFrame()
|
||||||
|
|
||||||
bf.WriteUint8(1) // resp_code
|
bf.WriteUint8(1) // resp_code
|
||||||
if s.server.erupeConfig.DevMode && s.server.erupeConfig.DevModeOptions.PatchServerManifest != "" && s.server.erupeConfig.DevModeOptions.PatchServerFile != "" {
|
if s.server.erupeConfig.DevMode && s.server.erupeConfig.PatchServerManifest != "" && s.server.erupeConfig.PatchServerFile != "" {
|
||||||
bf.WriteUint8(2)
|
bf.WriteUint8(2)
|
||||||
} else {
|
} else {
|
||||||
bf.WriteUint8(0)
|
bf.WriteUint8(0)
|
||||||
@@ -51,12 +43,12 @@ func (s *Session) makeSignInResp(uid int) []byte {
|
|||||||
bf.WriteUint8(1) // entrance server count
|
bf.WriteUint8(1) // entrance server count
|
||||||
bf.WriteUint8(uint8(len(chars))) // character count
|
bf.WriteUint8(uint8(len(chars))) // character count
|
||||||
bf.WriteUint32(0xFFFFFFFF) // login_token_number
|
bf.WriteUint32(0xFFFFFFFF) // login_token_number
|
||||||
bf.WriteBytes([]byte(token)) // login_token
|
bf.WriteBytes([]byte(sessToken)) // login_token
|
||||||
bf.WriteUint32(uint32(time.Now().Unix())) // current time
|
bf.WriteUint32(uint32(time.Now().Unix())) // current time
|
||||||
if s.server.erupeConfig.DevMode {
|
if s.server.erupeConfig.DevMode {
|
||||||
if s.server.erupeConfig.DevModeOptions.PatchServerManifest != "" && s.server.erupeConfig.DevModeOptions.PatchServerFile != "" {
|
if s.server.erupeConfig.PatchServerManifest != "" && s.server.erupeConfig.PatchServerFile != "" {
|
||||||
ps.Uint8(bf, s.server.erupeConfig.DevModeOptions.PatchServerManifest, false)
|
ps.Uint8(bf, s.server.erupeConfig.PatchServerManifest, false)
|
||||||
ps.Uint8(bf, s.server.erupeConfig.DevModeOptions.PatchServerFile, false)
|
ps.Uint8(bf, s.server.erupeConfig.PatchServerFile, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ps.Uint8(bf, fmt.Sprintf("%s:%d", s.server.erupeConfig.Host, s.server.erupeConfig.Entrance.Port), false)
|
ps.Uint8(bf, fmt.Sprintf("%s:%d", s.server.erupeConfig.Host, s.server.erupeConfig.Entrance.Port), false)
|
||||||
@@ -111,11 +103,11 @@ func (s *Session) makeSignInResp(uid int) []byte {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.server.erupeConfig.DevModeOptions.HideLoginNotice {
|
if s.server.erupeConfig.HideLoginNotice {
|
||||||
bf.WriteUint8(0)
|
bf.WriteUint8(0)
|
||||||
} else {
|
} else {
|
||||||
bf.WriteUint8(1) // Notice count
|
bf.WriteUint8(1) // Notice count
|
||||||
noticeText := s.server.erupeConfig.DevModeOptions.LoginNotice
|
noticeText := s.server.erupeConfig.LoginNotice
|
||||||
ps.Uint32(bf, noticeText, true)
|
ps.Uint32(bf, noticeText, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user