Implemented the ability to enable and disable commands in configuration as well as increased scope of the config to the entire project.

This commit is contained in:
Eclipse
2022-09-18 14:15:11 -04:00
parent e0176ca774
commit 44a42a3365
6 changed files with 309 additions and 165 deletions

View File

@@ -30,6 +30,31 @@
"bottoken": "",
"realtimeChannelID": ""
},
"ServerCommands": {
"enabled": true,
"Commands": [
{
"name": "Rights",
"enabled": true,
"prefix": "!rights"
},
{
"name": "Ravi",
"enabled": true,
"prefix": "!ravi"
},
{
"name": "Tele",
"enabled": true,
"prefix": "!tele"
},
{
"name": "Reload",
"enabled": true,
"prefix": "!reload"
}
]
},
"database": {
"host": "localhost",
"port": 5432,

View File

@@ -1,8 +1,11 @@
package config
import (
"fmt"
"log"
"net"
"os"
"time"
"github.com/spf13/viper"
)
@@ -16,6 +19,7 @@ type Config struct {
DevModeOptions DevModeOptions
Discord Discord
ServerCommands ServerCommands
Database Database
Launcher Launcher
Sign Sign
@@ -59,6 +63,18 @@ type Discord struct {
DevMode bool
}
// Server commands
type ServerCommands struct {
Enabled bool
Commands []ServerCommand
}
type ServerCommand struct {
Name string
Enabled bool
Prefix string
}
// Database holds the postgres database config.
type Database struct {
Host string
@@ -107,6 +123,28 @@ type EntranceChannelInfo struct {
CurrentPlayers uint16
}
var ErupeConfig *Config
func init() {
var err error
ErupeConfig, err = LoadConfig()
if err != nil {
preventClose(fmt.Sprintf("Failed to load config: %s", err.Error()))
}
}
func GetServerCommandByName(cmdName string) ServerCommand {
var val ServerCommand
for _, c := range ErupeConfig.ServerCommands.Commands {
if c.Name == cmdName {
return c
}
}
return val
}
// getOutboundIP4 gets the preferred outbound ip4 of this machine
// From https://stackoverflow.com/a/37382208
func getOutboundIP4() net.IP {
@@ -148,3 +186,20 @@ func LoadConfig() (*Config, error) {
return c, nil
}
func preventClose(text string) {
if ErupeConfig.DisableSoftCrash {
os.Exit(0)
}
fmt.Println("\nFailed to start Erupe:\n" + text)
go wait()
fmt.Println("\nPress Enter/Return to exit...")
fmt.Scanln()
os.Exit(0)
}
func wait() {
for {
time.Sleep(time.Millisecond * 100)
}
}

2
go.mod
View File

@@ -19,5 +19,5 @@ require (
golang.org/x/crypto v0.0.0-20211202192323-5770296d904e
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d // indirect
golang.org/x/text v0.3.7
golang.org/x/tools v0.1.8 // indirect
honnef.co/go/tools v0.3.3
)

9
go.sum
View File

@@ -38,6 +38,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw=
github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
@@ -295,6 +297,7 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211202192323-5770296d904e h1:MUP6MR3rJ7Gk9LEia0LP2ytiH6MuCfs7qYz+47jGdD8=
golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -307,6 +310,7 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp/typeparams v0.0.0-20220218215828-6cf2b201936e/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -334,6 +338,7 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -510,6 +515,8 @@ golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w=
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
golang.org/x/tools v0.1.11-0.20220513221640-090b14e8501f h1:OKYpQQVE3DKSc3r3zHVzq46vq5YH7x8xpR3/k9ixmUg=
golang.org/x/tools v0.1.11-0.20220513221640-090b14e8501f/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -638,6 +645,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.3.3 h1:oDx7VAwstgpYpb3wv0oxiZlxY+foCpRAwY7Vk6XpAgA=
honnef.co/go/tools v0.3.3/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

54
main.go
View File

@@ -20,8 +20,6 @@ import (
"go.uber.org/zap"
)
var erupeConfig *config.Config
// Temporary DB auto clean on startup for quick development & testing.
func cleanDB(db *sqlx.DB) {
_ = db.MustExec("DELETE FROM guild_characters")
@@ -39,25 +37,19 @@ func main() {
logger.Info("Starting Erupe")
// Load the configuration.
erupeConfig, err = config.LoadConfig()
if err != nil {
preventClose(fmt.Sprintf("Failed to load config: %s", err.Error()))
}
if erupeConfig.Database.Password == "" {
if config.ErupeConfig.Database.Password == "" {
preventClose("Database password is blank")
}
if net.ParseIP(erupeConfig.Host) == nil {
ips, _ := net.LookupIP(erupeConfig.Host)
if net.ParseIP(config.ErupeConfig.Host) == nil {
ips, _ := net.LookupIP(config.ErupeConfig.Host)
for _, ip := range ips {
if ip != nil {
erupeConfig.Host = ip.String()
config.ErupeConfig.Host = ip.String()
break
}
}
if net.ParseIP(erupeConfig.Host) == nil {
if net.ParseIP(config.ErupeConfig.Host) == nil {
preventClose("Invalid host address")
}
}
@@ -65,10 +57,10 @@ func main() {
// Discord bot
var discordBot *discordbot.DiscordBot = nil
if erupeConfig.Discord.Enabled {
if config.ErupeConfig.Discord.Enabled {
bot, err := discordbot.NewDiscordBot(discordbot.Options{
Logger: logger,
Config: erupeConfig,
Config: config.ErupeConfig,
})
if err != nil {
@@ -91,11 +83,11 @@ func main() {
// Create the postgres DB pool.
connectString := fmt.Sprintf(
"host=%s port=%d user=%s password=%s dbname= %s sslmode=disable",
erupeConfig.Database.Host,
erupeConfig.Database.Port,
erupeConfig.Database.User,
erupeConfig.Database.Password,
erupeConfig.Database.Database,
config.ErupeConfig.Database.Host,
config.ErupeConfig.Database.Port,
config.ErupeConfig.Database.User,
config.ErupeConfig.Database.Password,
config.ErupeConfig.Database.Database,
)
db, err := sqlx.Open("postgres", connectString)
@@ -117,7 +109,7 @@ func main() {
_ = db.MustExec("UPDATE characters SET cafe_time=0")
// Clean the DB if the option is on.
if erupeConfig.DevMode && erupeConfig.DevModeOptions.CleanDB {
if config.ErupeConfig.DevMode && config.ErupeConfig.DevModeOptions.CleanDB {
logger.Info("Cleaning DB")
cleanDB(db)
logger.Info("Done cleaning DB")
@@ -127,13 +119,13 @@ func main() {
// Launcher HTTP server.
var launcherServer *launcherserver.Server
if erupeConfig.DevMode && erupeConfig.DevModeOptions.EnableLauncherServer {
if config.ErupeConfig.DevMode && config.ErupeConfig.DevModeOptions.EnableLauncherServer {
launcherServer = launcherserver.NewServer(
&launcherserver.Config{
Logger: logger.Named("launcher"),
ErupeConfig: erupeConfig,
ErupeConfig: config.ErupeConfig,
DB: db,
UseOriginalLauncherFiles: erupeConfig.Launcher.UseOriginalLauncherFiles,
UseOriginalLauncherFiles: config.ErupeConfig.Launcher.UseOriginalLauncherFiles,
})
err = launcherServer.Start()
if err != nil {
@@ -146,7 +138,7 @@ func main() {
entranceServer := entranceserver.NewServer(
&entranceserver.Config{
Logger: logger.Named("entrance"),
ErupeConfig: erupeConfig,
ErupeConfig: config.ErupeConfig,
DB: db,
})
err = entranceServer.Start()
@@ -159,7 +151,7 @@ func main() {
signServer := signserver.NewServer(
&signserver.Config{
Logger: logger.Named("sign"),
ErupeConfig: erupeConfig,
ErupeConfig: config.ErupeConfig,
DB: db,
})
err = signServer.Start()
@@ -173,18 +165,18 @@ func main() {
si := 0
ci := 0
count := 1
for _, ee := range erupeConfig.Entrance.Entries {
for _, ee := range config.ErupeConfig.Entrance.Entries {
for i, ce := range ee.Channels {
sid := (4096 + si*256) + (16 + ci)
c := *channelserver.NewServer(&channelserver.Config{
ID: uint16(sid),
Logger: logger.Named("channel-" + fmt.Sprint(count)),
ErupeConfig: erupeConfig,
ErupeConfig: config.ErupeConfig,
DB: db,
DiscordBot: discordBot,
})
if ee.IP == "" {
c.IP = erupeConfig.Host
c.IP = config.ErupeConfig.Host
} else {
c.IP = ee.IP
}
@@ -223,7 +215,7 @@ func main() {
}
signServer.Shutdown()
entranceServer.Shutdown()
if erupeConfig.DevModeOptions.EnableLauncherServer {
if config.ErupeConfig.DevModeOptions.EnableLauncherServer {
launcherServer.Shutdown()
}
@@ -237,7 +229,7 @@ func wait() {
}
func preventClose(text string) {
if erupeConfig.DisableSoftCrash {
if config.ErupeConfig.DisableSoftCrash {
os.Exit(0)
}
fmt.Println("\nFailed to start Erupe:\n" + text)

View File

@@ -8,8 +8,11 @@ import (
"time"
"erupe-ce/common/byteframe"
"erupe-ce/config"
"erupe-ce/network/binpacket"
"erupe-ce/network/mhfpacket"
"go.uber.org/zap"
)
// MSG_SYS_CAST[ED]_BINARY types enum
@@ -29,6 +32,47 @@ const (
BroadcastTypeWorld = 0x0a
)
var raviCmd config.ServerCommand
var rightsCmd config.ServerCommand
var teleCmd config.ServerCommand
var reloadCmd config.ServerCommand
var logger *zap.Logger
func init() {
zapLogger, _ := zap.NewDevelopment()
defer zapLogger.Sync()
logger = zapLogger.Named("channelserver")
raviCmd = config.GetServerCommandByName("Ravi")
if raviCmd.Enabled {
logger.Info(raviCmd.Name + " command is enabled")
} else {
logger.Info(raviCmd.Name + " command is disabled")
}
rightsCmd = config.GetServerCommandByName("Rights")
if rightsCmd.Enabled {
logger.Info(rightsCmd.Name + " command is enabled")
} else {
logger.Info(rightsCmd.Name + " command is disabled")
}
teleCmd = config.GetServerCommandByName("Tele")
if teleCmd.Enabled {
logger.Info(teleCmd.Name + " command is enabled")
} else {
logger.Info(teleCmd.Name + " command is disabled")
}
reloadCmd = config.GetServerCommandByName("Reload")
if reloadCmd.Enabled {
logger.Info(reloadCmd.Name + " command is enabled")
} else {
logger.Info(reloadCmd.Name + " command is disabled")
}
}
func sendServerChatMessage(s *Session, message string) {
// Make the inside of the casted binary
bf := byteframe.NewByteFrame()
@@ -165,8 +209,9 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) {
fmt.Printf("Got chat message: %+v\n", chatMessage)
if strings.HasPrefix(chatMessage.Message, reloadCmd.Prefix) {
// Flush all objects and users and reload
if strings.HasPrefix(chatMessage.Message, "!reload") {
if reloadCmd.Enabled {
sendServerChatMessage(s, "Reloading players...")
var temp mhfpacket.MHFPacket
deleteNotif := byteframe.NewByteFrame()
@@ -223,10 +268,15 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) {
}
reloadNotif.WriteUint16(0x0010)
s.QueueSend(reloadNotif.Data())
} else {
sendServerChatMessage(s, reloadCmd.Name+" command is disabled")
}
}
if strings.HasPrefix(chatMessage.Message, rightsCmd.Prefix) {
// Set account rights
if strings.HasPrefix(chatMessage.Message, "!rights") {
if rightsCmd.Enabled {
var v uint32
n, err := fmt.Sscanf(chatMessage.Message, "!rights %d", &v)
if err != nil || n != 1 {
@@ -237,6 +287,10 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) {
sendServerChatMessage(s, fmt.Sprintf("Set rights integer: %d", v))
}
}
} else {
sendServerChatMessage(s, rightsCmd.Name+" command is disabled")
}
}
// Discord integration
@@ -244,8 +298,9 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) {
s.server.DiscordChannelSend(chatMessage.SenderName, chatMessage.Message)
}
if strings.HasPrefix(chatMessage.Message, raviCmd.Prefix) {
// RAVI COMMANDS V2
if strings.HasPrefix(chatMessage.Message, "!ravi") {
if raviCmd.Enabled {
if getRaviSemaphore(s) != "" {
s.server.raviente.Lock()
if !strings.HasPrefix(chatMessage.Message, "!ravi ") {
@@ -302,10 +357,15 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) {
} else {
sendServerChatMessage(s, "No one has joined the Great Slaying!")
}
} else {
sendServerChatMessage(s, raviCmd.Name+" command is disabled")
}
}
// END RAVI COMMANDS V2
if strings.HasPrefix(chatMessage.Message, "!tele ") {
if strings.HasPrefix(chatMessage.Message, teleCmd.Prefix) {
if teleCmd.Enabled {
var x, y int16
n, err := fmt.Sscanf(chatMessage.Message, "!tele %d %d", &x, &y)
if err != nil || n != 2 {
@@ -327,6 +387,9 @@ func handleMsgSysCastBinary(s *Session, p mhfpacket.MHFPacket) {
RawDataPayload: payloadBytes,
})
}
} else {
sendServerChatMessage(s, teleCmd.Name+" command is disabled")
}
}
}
}