mirror of
https://github.com/Mezeporta/Erupe.git
synced 2025-12-12 23:14:36 +01:00
Compare commits
1 Commits
5f265ee291
...
fix/refact
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4f889b1bf1 |
@@ -1,6 +1,7 @@
|
||||
package token
|
||||
|
||||
import (
|
||||
crand "crypto/rand"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
@@ -20,3 +21,10 @@ func Generate(length int) string {
|
||||
func RNG() *rand.Rand {
|
||||
return rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
}
|
||||
|
||||
// RandBytes returns x random bytes
|
||||
func RandBytes(x int) []byte {
|
||||
y := make([]byte, x)
|
||||
crand.Read(y)
|
||||
return y
|
||||
}
|
||||
|
||||
66
config.json
66
config.json
@@ -156,45 +156,37 @@
|
||||
"Links": []
|
||||
},
|
||||
"Channel": {
|
||||
"Enabled": true
|
||||
"Enabled": true,
|
||||
"Worlds": [
|
||||
{
|
||||
"Name": "Novice", "Description": "Up to 2★", "IP": "", "Type": 3, "Recommended": 1, "AllowedClientFlags": 0,
|
||||
"Lands": [{"MaxPlayers": 100}]
|
||||
}, {
|
||||
"Name": "Rookie", "Description": "Up to 4★", "IP": "", "Type": 3, "Recommended": 2, "AllowedClientFlags": 0,
|
||||
"Lands": [{"MaxPlayers": 100}]
|
||||
}, {
|
||||
"Name": "Sincere", "Description": "All Quests", "IP": "", "Type": 1, "Recommended": 0, "AllowedClientFlags": 0,
|
||||
"Lands": [{"MaxPlayers": 100}]
|
||||
}, {
|
||||
"Name": "Brave", "Description": "Only G Quests", "IP": "", "Type": 1, "Recommended": 5, "AllowedClientFlags": 0,
|
||||
"Lands": [{"MaxPlayers": 100}]
|
||||
}, {
|
||||
"Name": "Noble", "Description": "All Quests", "IP": "", "Type": 2, "Recommended": 0, "AllowedClientFlags": 0,
|
||||
"Lands": [{"MaxPlayers": 100}, {"MaxPlayers": 100}]
|
||||
}, {
|
||||
"Name": "Spirit", "Description": "All Quests", "IP": "", "Type": 4, "Recommended": 0, "AllowedClientFlags": 0,
|
||||
"Lands": [{"MaxPlayers": 100}, {"MaxPlayers": 100}]
|
||||
}, {
|
||||
"Name": "Legend", "Description": "All Quests", "IP": "", "Type": 5, "Recommended": 0, "AllowedClientFlags": 0,
|
||||
"Lands": [{"MaxPlayers": 100}]
|
||||
}, {
|
||||
"Name": "Fancy", "Description": "Minigames!", "IP": "", "Type": 6, "Recommended": 6, "AllowedClientFlags": 0,
|
||||
"Lands": [{"MaxPlayers": 80}]
|
||||
}
|
||||
]
|
||||
},
|
||||
"Entrance": {
|
||||
"Enabled": true,
|
||||
"Port": 53310,
|
||||
"Entries": [
|
||||
{
|
||||
"Name": "Newbie", "Description": "", "IP": "", "Type": 3, "Recommended": 2, "AllowedClientFlags": 0,
|
||||
"Channels": [
|
||||
{ "Port": 54001, "MaxPlayers": 100 },
|
||||
{ "Port": 54002, "MaxPlayers": 100 }
|
||||
]
|
||||
}, {
|
||||
"Name": "Normal", "Description": "", "IP": "", "Type": 1, "Recommended": 0, "AllowedClientFlags": 0,
|
||||
"Channels": [
|
||||
{ "Port": 54003, "MaxPlayers": 100 },
|
||||
{ "Port": 54004, "MaxPlayers": 100 }
|
||||
]
|
||||
}, {
|
||||
"Name": "Cities", "Description": "", "IP": "", "Type": 2, "Recommended": 0, "AllowedClientFlags": 0,
|
||||
"Channels": [
|
||||
{ "Port": 54005, "MaxPlayers": 100 }
|
||||
]
|
||||
}, {
|
||||
"Name": "Tavern", "Description": "", "IP": "", "Type": 4, "Recommended": 0, "AllowedClientFlags": 0,
|
||||
"Channels": [
|
||||
{ "Port": 54006, "MaxPlayers": 100 }
|
||||
]
|
||||
}, {
|
||||
"Name": "Return", "Description": "", "IP": "", "Type": 5, "Recommended": 0, "AllowedClientFlags": 0,
|
||||
"Channels": [
|
||||
{ "Port": 54007, "MaxPlayers": 100 }
|
||||
]
|
||||
}, {
|
||||
"Name": "MezFes", "Description": "", "IP": "", "Type": 6, "Recommended": 6, "AllowedClientFlags": 0,
|
||||
"Channels": [
|
||||
{ "Port": 54008, "MaxPlayers": 100 }
|
||||
]
|
||||
}
|
||||
]
|
||||
"Port": 53310
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,35 +228,29 @@ type SignV2Link struct {
|
||||
|
||||
type Channel struct {
|
||||
Enabled bool
|
||||
Worlds []World
|
||||
}
|
||||
|
||||
type World struct {
|
||||
IP string
|
||||
Type uint8
|
||||
Season uint8
|
||||
Recommended uint8
|
||||
Name string
|
||||
Description string
|
||||
AllowedClientFlags uint32
|
||||
Lands []Land
|
||||
}
|
||||
|
||||
type Land struct {
|
||||
Port uint16
|
||||
MaxPlayers uint16
|
||||
}
|
||||
|
||||
// Entrance holds the entrance server config.
|
||||
type Entrance struct {
|
||||
Enabled bool
|
||||
Port uint16
|
||||
Entries []EntranceServerInfo
|
||||
}
|
||||
|
||||
// EntranceServerInfo represents an entry in the serverlist.
|
||||
type EntranceServerInfo struct {
|
||||
IP string
|
||||
Type uint8 // Server type. 0=?, 1=open, 2=cities, 3=newbie, 4=bar
|
||||
Season uint8 // Server activity. 0 = green, 1 = orange, 2 = blue
|
||||
Recommended uint8 // Something to do with server recommendation on 0, 3, and 5.
|
||||
Name string // Server name, 66 byte null terminated Shift-JIS(JP) or Big5(TW).
|
||||
Description string // Server description
|
||||
// 4096(PC, PS3/PS4)?, 8258(PC, PS3/PS4)?, 8192 == nothing?
|
||||
// THIS ONLY EXISTS IF Binary8Header.type == "SV2", NOT "SVR"!
|
||||
AllowedClientFlags uint32
|
||||
|
||||
Channels []EntranceChannelInfo
|
||||
}
|
||||
|
||||
// EntranceChannelInfo represents an entry in a server's channel list.
|
||||
type EntranceChannelInfo struct {
|
||||
Port uint16
|
||||
MaxPlayers uint16
|
||||
CurrentPlayers uint16
|
||||
}
|
||||
|
||||
var ErupeConfig *Config
|
||||
|
||||
66
main.go
66
main.go
@@ -7,6 +7,7 @@ import (
|
||||
"os"
|
||||
"os/signal"
|
||||
"runtime/debug"
|
||||
"slices"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
@@ -150,7 +151,7 @@ func main() {
|
||||
entranceServer = entranceserver.NewServer(
|
||||
&entranceserver.Config{
|
||||
Logger: logger.Named("entrance"),
|
||||
ErupeConfig: _config.ErupeConfig,
|
||||
ErupeConfig: config,
|
||||
DB: db,
|
||||
})
|
||||
err = entranceServer.Start()
|
||||
@@ -169,7 +170,7 @@ func main() {
|
||||
signServer = signserver.NewServer(
|
||||
&signserver.Config{
|
||||
Logger: logger.Named("sign"),
|
||||
ErupeConfig: _config.ErupeConfig,
|
||||
ErupeConfig: config,
|
||||
DB: db,
|
||||
})
|
||||
err = signServer.Start()
|
||||
@@ -187,7 +188,7 @@ func main() {
|
||||
newSignServer = signv2server.NewServer(
|
||||
&signv2server.Config{
|
||||
Logger: logger.Named("sign"),
|
||||
ErupeConfig: _config.ErupeConfig,
|
||||
ErupeConfig: config,
|
||||
DB: db,
|
||||
})
|
||||
err = newSignServer.Start()
|
||||
@@ -199,20 +200,20 @@ func main() {
|
||||
logger.Info("SignV2: Disabled")
|
||||
}
|
||||
|
||||
var channels []*channelserver.Server
|
||||
var worlds [][]*channelserver.Server
|
||||
var ports []uint16
|
||||
|
||||
if config.Channel.Enabled {
|
||||
channelQuery := ""
|
||||
si := 0
|
||||
ci := 0
|
||||
count := 1
|
||||
for j, ee := range config.Entrance.Entries {
|
||||
for i, ce := range ee.Channels {
|
||||
sid := (4096 + si*256) + (16 + ci)
|
||||
var count int
|
||||
for j, ee := range config.Channel.Worlds {
|
||||
var lands []*channelserver.Server
|
||||
for i, ce := range ee.Lands {
|
||||
sid := (4096 + j*256) + (16 + i)
|
||||
c := *channelserver.NewServer(&channelserver.Config{
|
||||
ID: uint16(sid),
|
||||
Logger: logger.Named("channel-" + fmt.Sprint(count)),
|
||||
ErupeConfig: _config.ErupeConfig,
|
||||
Logger: logger.Named("channel-" + fmt.Sprint(count+1)),
|
||||
ErupeConfig: config,
|
||||
DB: db,
|
||||
DiscordBot: discordBot,
|
||||
})
|
||||
@@ -221,28 +222,41 @@ func main() {
|
||||
} else {
|
||||
c.IP = ee.IP
|
||||
}
|
||||
c.Port = ce.Port
|
||||
if ce.Port == 0 {
|
||||
for i := 0; ; i++ {
|
||||
port := uint16(54001 + i)
|
||||
if !slices.Contains(ports, port) {
|
||||
ce.Port = port
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if slices.Contains(ports, ce.Port) {
|
||||
preventClose("Channel: Failed to start, duplicate port")
|
||||
break
|
||||
} else {
|
||||
ports = append(ports, ce.Port)
|
||||
c.Port = ce.Port
|
||||
}
|
||||
c.GlobalID = fmt.Sprintf("%02d%02d", j+1, i+1)
|
||||
err = c.Start()
|
||||
if err != nil {
|
||||
preventClose(fmt.Sprintf("Channel: Failed to start, %s", err.Error()))
|
||||
} else {
|
||||
channelQuery += fmt.Sprintf(`INSERT INTO servers (server_id, current_players, world_name, world_description, land) VALUES (%d, 0, '%s', '%s', %d);`, sid, ee.Name, ee.Description, i+1)
|
||||
channels = append(channels, &c)
|
||||
logger.Info(fmt.Sprintf("Channel %d (%d): Started successfully", count, ce.Port))
|
||||
ci++
|
||||
lands = append(lands, &c)
|
||||
logger.Info(fmt.Sprintf("Channel %d (%d): Started successfully", count, c.Port))
|
||||
count++
|
||||
}
|
||||
}
|
||||
ci = 0
|
||||
si++
|
||||
worlds = append(worlds, lands)
|
||||
}
|
||||
|
||||
// Register all servers in DB
|
||||
_ = db.MustExec(channelQuery)
|
||||
|
||||
for _, c := range channels {
|
||||
c.Channels = channels
|
||||
if config.Entrance.Enabled {
|
||||
entranceServer.SetWorlds(worlds)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,8 +270,10 @@ func main() {
|
||||
if !config.DisableSoftCrash {
|
||||
for i := 0; i < 10; i++ {
|
||||
message := fmt.Sprintf("Shutting down in %d...", 10-i)
|
||||
for _, c := range channels {
|
||||
c.BroadcastChatMessage(message)
|
||||
for _, w := range worlds {
|
||||
for _, l := range w {
|
||||
l.BroadcastChatMessage(message)
|
||||
}
|
||||
}
|
||||
logger.Info(message)
|
||||
time.Sleep(time.Second)
|
||||
@@ -265,8 +281,10 @@ func main() {
|
||||
}
|
||||
|
||||
if config.Channel.Enabled {
|
||||
for _, c := range channels {
|
||||
c.Shutdown()
|
||||
for _, w := range worlds {
|
||||
for _, l := range w {
|
||||
l.Shutdown()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -419,3 +419,7 @@ func (s *Server) Season() uint8 {
|
||||
sid := int64(((s.ID & 0xFF00) - 4096) / 256)
|
||||
return uint8(((TimeAdjusted().Unix() / 86400) + sid) % 3)
|
||||
}
|
||||
|
||||
func (s *Server) Players() uint16 {
|
||||
return uint16(len(s.sessions))
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package entranceserver
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"erupe-ce/server/channelserver"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
@@ -19,6 +20,7 @@ type Server struct {
|
||||
sync.Mutex
|
||||
logger *zap.Logger
|
||||
erupeConfig *_config.Config
|
||||
worlds [][]*channelserver.Server
|
||||
db *sqlx.DB
|
||||
listener net.Listener
|
||||
isShuttingDown bool
|
||||
@@ -68,6 +70,10 @@ func (s *Server) Shutdown() {
|
||||
s.listener.Close()
|
||||
}
|
||||
|
||||
func (s *Server) SetWorlds(c [][]*channelserver.Server) {
|
||||
s.worlds = c
|
||||
}
|
||||
|
||||
// acceptClients handles accepting new clients in a loop.
|
||||
func (s *Server) acceptClients() {
|
||||
for {
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"erupe-ce/common/stringsupport"
|
||||
"erupe-ce/common/token"
|
||||
_config "erupe-ce/config"
|
||||
"fmt"
|
||||
"net"
|
||||
@@ -13,10 +14,8 @@ import (
|
||||
)
|
||||
|
||||
func encodeServerInfo(config *_config.Config, s *Server, local bool) []byte {
|
||||
serverInfos := config.Entrance.Entries
|
||||
bf := byteframe.NewByteFrame()
|
||||
|
||||
for serverIdx, si := range serverInfos {
|
||||
for i, si := range config.Channel.Worlds {
|
||||
// Prevent MezFes Worlds displaying on Z1
|
||||
if config.RealClientMode <= _config.Z1 {
|
||||
if si.Type == 6 {
|
||||
@@ -29,7 +28,7 @@ func encodeServerInfo(config *_config.Config, s *Server, local bool) []byte {
|
||||
}
|
||||
}
|
||||
|
||||
sid := (4096 + serverIdx*256) * 6000
|
||||
sid := (4096 + i*256) * 6000
|
||||
if si.IP == "" {
|
||||
si.IP = config.Host
|
||||
}
|
||||
@@ -38,11 +37,11 @@ func encodeServerInfo(config *_config.Config, s *Server, local bool) []byte {
|
||||
} else {
|
||||
bf.WriteUint32(binary.LittleEndian.Uint32(net.ParseIP(si.IP).To4()))
|
||||
}
|
||||
bf.WriteUint16(16 + uint16(serverIdx))
|
||||
bf.WriteUint16(16 + uint16(i))
|
||||
bf.WriteUint16(0x0000)
|
||||
bf.WriteUint16(uint16(len(si.Channels)))
|
||||
bf.WriteUint16(uint16(len(si.Lands)))
|
||||
bf.WriteUint8(si.Type)
|
||||
bf.WriteUint8(uint8(((channelserver.TimeAdjusted().Unix() / 86400) + int64(serverIdx)) % 3))
|
||||
bf.WriteUint8(uint8(((channelserver.TimeAdjusted().Unix() / 86400) + int64(i)) % 3))
|
||||
if s.erupeConfig.RealClientMode >= _config.G1 {
|
||||
bf.WriteUint8(si.Recommended)
|
||||
}
|
||||
@@ -67,15 +66,15 @@ func encodeServerInfo(config *_config.Config, s *Server, local bool) []byte {
|
||||
bf.WriteUint32(si.AllowedClientFlags)
|
||||
}
|
||||
|
||||
for channelIdx, ci := range si.Channels {
|
||||
sid = (4096 + serverIdx*256) + (16 + channelIdx)
|
||||
for j, land := range si.Lands {
|
||||
sid = (4096 + i*256) + (16 + j)
|
||||
if _config.ErupeConfig.DevMode && _config.ErupeConfig.ProxyPort != 0 {
|
||||
bf.WriteUint16(_config.ErupeConfig.ProxyPort)
|
||||
} else {
|
||||
bf.WriteUint16(ci.Port)
|
||||
bf.WriteUint16(land.Port)
|
||||
}
|
||||
bf.WriteUint16(16 + uint16(channelIdx))
|
||||
bf.WriteUint16(ci.MaxPlayers)
|
||||
bf.WriteUint16(16 + uint16(j))
|
||||
bf.WriteUint16(land.MaxPlayers)
|
||||
var currentPlayers uint16
|
||||
s.db.QueryRow("SELECT current_players FROM servers WHERE server_id=$1", sid).Scan(¤tPlayers)
|
||||
bf.WriteUint16(currentPlayers)
|
||||
@@ -115,11 +114,11 @@ func makeHeader(data []byte, respType string, entryCount uint16, key byte) []byt
|
||||
}
|
||||
|
||||
func makeSv2Resp(config *_config.Config, s *Server, local bool) []byte {
|
||||
serverInfos := config.Entrance.Entries
|
||||
worlds := config.Channel.Worlds
|
||||
// Decrease by the number of MezFes Worlds
|
||||
var mf int
|
||||
if config.RealClientMode <= _config.Z1 {
|
||||
for _, si := range serverInfos {
|
||||
for _, si := range worlds {
|
||||
if si.Type == 6 {
|
||||
mf++
|
||||
}
|
||||
@@ -128,7 +127,7 @@ func makeSv2Resp(config *_config.Config, s *Server, local bool) []byte {
|
||||
// and Return Worlds
|
||||
var ret int
|
||||
if config.RealClientMode <= _config.G6 {
|
||||
for _, si := range serverInfos {
|
||||
for _, si := range worlds {
|
||||
if si.Type == 5 {
|
||||
ret++
|
||||
}
|
||||
@@ -146,7 +145,7 @@ func makeSv2Resp(config *_config.Config, s *Server, local bool) []byte {
|
||||
}
|
||||
|
||||
bf := byteframe.NewByteFrame()
|
||||
bf.WriteBytes(makeHeader(rawServerData, respType, uint16(len(serverInfos)-(mf+ret)), 0x00))
|
||||
bf.WriteBytes(makeHeader(rawServerData, respType, uint16(len(worlds)-(mf+ret)), token.RandBytes(1)[0]))
|
||||
return bf.Data()
|
||||
}
|
||||
|
||||
@@ -172,5 +171,5 @@ func makeUsrResp(pkt []byte, s *Server) []byte {
|
||||
fmt.Printf("[Server] -> [Client]\nData [%d bytes]:\n%s\n", len(resp.Data()), hex.Dump(resp.Data()))
|
||||
}
|
||||
|
||||
return makeHeader(resp.Data(), "USR", userEntries, 0x00)
|
||||
return makeHeader(resp.Data(), "USR", userEntries, token.RandBytes(1)[0])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user