mirror of
https://github.com/Mezeporta/Erupe.git
synced 2025-12-24 21:04:39 +01:00
307 lines
7.4 KiB
Go
307 lines
7.4 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/rivo/tview"
|
|
"net"
|
|
"os"
|
|
"runtime/debug"
|
|
"strconv"
|
|
"time"
|
|
|
|
"erupe-ce/config"
|
|
"erupe-ce/server/channelserver"
|
|
"erupe-ce/server/discordbot"
|
|
"erupe-ce/server/entranceserver"
|
|
"erupe-ce/server/signserver"
|
|
"erupe-ce/server/signv2server"
|
|
|
|
"github.com/jmoiron/sqlx"
|
|
_ "github.com/lib/pq"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
// Temporary DB auto clean on startup for quick development & testing.
|
|
func cleanDB(db *sqlx.DB) {
|
|
_ = db.MustExec("DELETE FROM guild_characters")
|
|
_ = db.MustExec("DELETE FROM guilds")
|
|
_ = db.MustExec("DELETE FROM characters")
|
|
_ = db.MustExec("DELETE FROM sign_sessions")
|
|
_ = db.MustExec("DELETE FROM users")
|
|
}
|
|
|
|
var Commit = func() string {
|
|
if info, ok := debug.ReadBuildInfo(); ok {
|
|
for _, setting := range info.Settings {
|
|
if setting.Key == "vcs.revision" {
|
|
return setting.Value[:7]
|
|
}
|
|
}
|
|
}
|
|
return "unknown"
|
|
}
|
|
|
|
func main() {
|
|
var err error
|
|
zapLogger, _ := zap.NewDevelopment()
|
|
defer zapLogger.Sync()
|
|
logger := zapLogger.Named("main")
|
|
|
|
logger.Info(fmt.Sprintf("Starting Erupe (9.2b-%s)", Commit()))
|
|
|
|
if config.ErupeConfig.Database.Password == "" {
|
|
preventClose("Database password is blank")
|
|
}
|
|
|
|
if net.ParseIP(config.ErupeConfig.Host) == nil {
|
|
ips, _ := net.LookupIP(config.ErupeConfig.Host)
|
|
for _, ip := range ips {
|
|
if ip != nil {
|
|
config.ErupeConfig.Host = ip.String()
|
|
break
|
|
}
|
|
}
|
|
if net.ParseIP(config.ErupeConfig.Host) == nil {
|
|
preventClose("Invalid host address")
|
|
}
|
|
}
|
|
|
|
// Discord bot
|
|
var discordBot *discordbot.DiscordBot = nil
|
|
|
|
if config.ErupeConfig.Discord.Enabled {
|
|
bot, err := discordbot.NewDiscordBot(discordbot.Options{
|
|
Logger: logger,
|
|
Config: config.ErupeConfig,
|
|
})
|
|
|
|
if err != nil {
|
|
preventClose(fmt.Sprintf("Failed to create Discord bot: %s", err.Error()))
|
|
}
|
|
|
|
// Discord bot
|
|
err = bot.Start()
|
|
|
|
if err != nil {
|
|
preventClose(fmt.Sprintf("Failed to start Discord bot: %s", err.Error()))
|
|
}
|
|
|
|
discordBot = bot
|
|
logger.Info("Discord bot is enabled")
|
|
} else {
|
|
logger.Info("Discord bot is disabled")
|
|
}
|
|
|
|
// Create the postgres DB pool.
|
|
connectString := fmt.Sprintf(
|
|
"host='%s' port='%d' user='%s' password='%s' dbname='%s' sslmode=disable",
|
|
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)
|
|
if err != nil {
|
|
preventClose(fmt.Sprintf("Failed to open SQL database: %s", err.Error()))
|
|
}
|
|
|
|
// Test the DB connection.
|
|
err = db.Ping()
|
|
if err != nil {
|
|
preventClose(fmt.Sprintf("Failed to ping database: %s", err.Error()))
|
|
}
|
|
logger.Info("Connected to database")
|
|
|
|
// Clear stale data
|
|
_ = db.MustExec("DELETE FROM sign_sessions")
|
|
_ = db.MustExec("DELETE FROM servers")
|
|
|
|
// Clean the DB if the option is on.
|
|
if config.ErupeConfig.DevMode && config.ErupeConfig.DevModeOptions.CleanDB {
|
|
logger.Info("Cleaning DB")
|
|
cleanDB(db)
|
|
logger.Info("Done cleaning DB")
|
|
}
|
|
|
|
logger.Info(fmt.Sprintf("Server Time: %s", channelserver.TimeAdjusted().String()))
|
|
|
|
// Now start our server(s).
|
|
|
|
// Entrance server.
|
|
|
|
var entranceServer *entranceserver.Server
|
|
if config.ErupeConfig.Entrance.Enabled {
|
|
entranceServer = entranceserver.NewServer(
|
|
&entranceserver.Config{
|
|
Logger: logger.Named("entrance"),
|
|
ErupeConfig: config.ErupeConfig,
|
|
DB: db,
|
|
})
|
|
err = entranceServer.Start()
|
|
if err != nil {
|
|
preventClose(fmt.Sprintf("Failed to start entrance server: %s", err.Error()))
|
|
}
|
|
logger.Info("Started entrance server")
|
|
}
|
|
|
|
// Sign server.
|
|
|
|
var signServer *signserver.Server
|
|
if config.ErupeConfig.Sign.Enabled {
|
|
signServer = signserver.NewServer(
|
|
&signserver.Config{
|
|
Logger: logger.Named("sign"),
|
|
ErupeConfig: config.ErupeConfig,
|
|
DB: db,
|
|
})
|
|
err = signServer.Start()
|
|
if err != nil {
|
|
preventClose(fmt.Sprintf("Failed to start sign server: %s", err.Error()))
|
|
}
|
|
logger.Info("Started sign server")
|
|
}
|
|
|
|
// New Sign server
|
|
var newSignServer *signv2server.Server
|
|
if config.ErupeConfig.SignV2.Enabled {
|
|
newSignServer = signv2server.NewServer(
|
|
&signv2server.Config{
|
|
Logger: logger.Named("sign"),
|
|
ErupeConfig: config.ErupeConfig,
|
|
DB: db,
|
|
})
|
|
err = newSignServer.Start()
|
|
if err != nil {
|
|
preventClose(fmt.Sprintf("Failed to start sign-v2 server: %s", err.Error()))
|
|
}
|
|
logger.Info("Started new sign server")
|
|
}
|
|
|
|
var channels []*channelserver.Server
|
|
|
|
if config.ErupeConfig.Channel.Enabled {
|
|
channelQuery := ""
|
|
si := 0
|
|
ci := 0
|
|
count := 1
|
|
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: config.ErupeConfig,
|
|
DB: db,
|
|
DiscordBot: discordBot,
|
|
})
|
|
if ee.IP == "" {
|
|
c.IP = config.ErupeConfig.Host
|
|
} else {
|
|
c.IP = ee.IP
|
|
}
|
|
c.Port = ce.Port
|
|
err = c.Start()
|
|
if err != nil {
|
|
preventClose(fmt.Sprintf("Failed to start channel server: %s", err.Error()))
|
|
} else {
|
|
channelQuery += fmt.Sprintf(`INSERT INTO servers (server_id, season, current_players, world_name, world_description, land) VALUES (%d, %d, 0, '%s', '%s', %d);`, sid, si%3, ee.Name, ee.Description, i+1)
|
|
channels = append(channels, &c)
|
|
logger.Info(fmt.Sprintf("Started channel server %d on port %d", count, ce.Port))
|
|
ci++
|
|
count++
|
|
}
|
|
}
|
|
ci = 0
|
|
si++
|
|
}
|
|
|
|
// Register all servers in DB
|
|
_ = db.MustExec(channelQuery)
|
|
|
|
for _, c := range channels {
|
|
c.Channels = channels
|
|
}
|
|
}
|
|
|
|
logger.Info("Finished starting Erupe")
|
|
|
|
app := tview.NewApplication()
|
|
|
|
channelNode := tview.NewTreeNode("Channel")
|
|
|
|
browser := tview.NewTreeView().SetRoot(channelNode).SetCurrentNode(channelNode)
|
|
browser.SetTitle("Channel Browser").SetBorder(true)
|
|
|
|
erupeNode := tview.NewTreeNode("Erupe")
|
|
|
|
channelsList := tview.NewTreeView().SetRoot(erupeNode).SetCurrentNode(erupeNode)
|
|
channelsList.SetTitle("Channels").SetBorder(true)
|
|
|
|
for _, channel := range channels {
|
|
temp := tview.NewTreeNode(strconv.Itoa(int(channel.Port))).SetReference(channel)
|
|
erupeNode.AddChild(temp)
|
|
}
|
|
|
|
channelsList.SetSelectedFunc(func(node *tview.TreeNode) {
|
|
channelNode.ClearChildren()
|
|
ref := node.GetReference()
|
|
for id, stage := range ref.(*channelserver.Server).Stages() {
|
|
stageNode := tview.NewTreeNode(id).SetExpanded(true)
|
|
for i, j := range stage.Clients() {
|
|
charNode := tview.NewTreeNode(i.Name + " (" + strconv.Itoa(int(j)) + ")")
|
|
stageNode.AddChild(charNode)
|
|
}
|
|
channelNode.AddChild(stageNode)
|
|
}
|
|
})
|
|
|
|
flex := tview.NewFlex().
|
|
AddItem(channelsList, 0, 1, true).
|
|
AddItem(browser, 0, 3, false)
|
|
|
|
app.SetRoot(flex, true).EnableMouse(true)
|
|
|
|
if err = app.Run(); err != nil {
|
|
logger.Error("Error in TUI")
|
|
}
|
|
|
|
logger.Info("Shutting down...")
|
|
|
|
if config.ErupeConfig.Channel.Enabled {
|
|
for _, c := range channels {
|
|
c.Shutdown()
|
|
}
|
|
}
|
|
|
|
if config.ErupeConfig.Sign.Enabled {
|
|
signServer.Shutdown()
|
|
}
|
|
|
|
if config.ErupeConfig.SignV2.Enabled {
|
|
newSignServer.Shutdown()
|
|
}
|
|
|
|
if config.ErupeConfig.Entrance.Enabled {
|
|
entranceServer.Shutdown()
|
|
}
|
|
}
|
|
|
|
func wait() {
|
|
for {
|
|
time.Sleep(time.Millisecond * 100)
|
|
}
|
|
}
|
|
|
|
func preventClose(text string) {
|
|
if config.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)
|
|
}
|