diff --git a/config.json b/config.json index a4ef568cf..2b836ab03 100644 --- a/config.json +++ b/config.json @@ -195,8 +195,8 @@ "Enabled": true, "Port": 53312 }, - "SignV2": { - "Enabled": false, + "API": { + "Enabled": true, "Port": 8080, "PatchServer": "", "Banners": [], diff --git a/config/config.go b/config/config.go index 6e86c60ed..52642956b 100644 --- a/config/config.go +++ b/config/config.go @@ -95,7 +95,7 @@ type Config struct { Courses []Course Database Database Sign Sign - SignV2 SignV2 + API API Channel Channel Entrance Entrance } @@ -237,29 +237,29 @@ type Sign struct { Port int } -// SignV2 holds the new sign server config -type SignV2 struct { +// API holds server config +type API struct { Enabled bool Port int PatchServer string - Banners []SignV2Banner - Messages []SignV2Message - Links []SignV2Link + Banners []APISignBanner + Messages []APISignMessage + Links []APISignLink } -type SignV2Banner struct { +type APISignBanner struct { Src string `json:"src"` // Displayed image URL Link string `json:"link"` // Link accessed on click } -type SignV2Message struct { +type APISignMessage struct { Message string `json:"message"` // Displayed message Date int64 `json:"date"` // Displayed date Kind int `json:"kind"` // 0 for 'Default', 1 for 'New' Link string `json:"link"` // Link accessed on click } -type SignV2Link struct { +type APISignLink struct { Name string `json:"name"` // Displayed name Icon string `json:"icon"` // Displayed icon. It will be cast as a monochrome color as long as it is transparent. Link string `json:"link"` // Link accessed on click diff --git a/main.go b/main.go index a7d368930..2c776a78c 100644 --- a/main.go +++ b/main.go @@ -10,11 +10,11 @@ import ( "syscall" "time" + "erupe-ce/server/api" "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" @@ -181,21 +181,21 @@ func main() { } // New Sign server - var newSignServer *signv2server.Server - if config.SignV2.Enabled { - newSignServer = signv2server.NewServer( - &signv2server.Config{ + var ApiServer *api.APIServer + if config.API.Enabled { + ApiServer = api.NewAPIServer( + &api.Config{ Logger: logger.Named("sign"), ErupeConfig: _config.ErupeConfig, DB: db, }) - err = newSignServer.Start() + err = ApiServer.Start() if err != nil { - preventClose(fmt.Sprintf("SignV2: Failed to start, %s", err.Error())) + preventClose(fmt.Sprintf("API: Failed to start, %s", err.Error())) } - logger.Info("SignV2: Started successfully") + logger.Info("API: Started successfully") } else { - logger.Info("SignV2: Disabled") + logger.Info("API: Disabled") } var channels []*channelserver.Server @@ -273,8 +273,8 @@ func main() { signServer.Shutdown() } - if config.SignV2.Enabled { - newSignServer.Shutdown() + if config.API.Enabled { + ApiServer.Shutdown() } if config.Entrance.Enabled { diff --git a/server/signv2server/signv2_server.go b/server/api/api_server.go similarity index 86% rename from server/signv2server/signv2_server.go rename to server/api/api_server.go index 32c852e30..3774f3fb8 100644 --- a/server/signv2server/signv2_server.go +++ b/server/api/api_server.go @@ -1,4 +1,4 @@ -package signv2server +package api import ( "context" @@ -21,8 +21,8 @@ type Config struct { ErupeConfig *_config.Config } -// Server is the MHF custom launcher sign server. -type Server struct { +// APIServer is Erupes Standard API interface +type APIServer struct { sync.Mutex logger *zap.Logger erupeConfig *_config.Config @@ -31,9 +31,9 @@ type Server struct { isShuttingDown bool } -// NewServer creates a new Server type. -func NewServer(config *Config) *Server { - s := &Server{ +// NewAPIServer creates a new Server type. +func NewAPIServer(config *Config) *APIServer { + s := &APIServer{ logger: config.Logger, erupeConfig: config.ErupeConfig, db: config.DB, @@ -43,7 +43,7 @@ func NewServer(config *Config) *Server { } // Start starts the server in a new goroutine. -func (s *Server) Start() error { +func (s *APIServer) Start() error { // Set up the routes responsible for serving the launcher HTML, serverlist, unique name check, and JP auth. r := mux.NewRouter() r.HandleFunc("/launcher", s.Launcher) @@ -56,7 +56,7 @@ func (s *Server) Start() error { r.HandleFunc("/api/ss/bbs/{id}", s.ScreenShotGet) handler := handlers.CORS(handlers.AllowedHeaders([]string{"Content-Type"}))(r) s.httpServer.Handler = handlers.LoggingHandler(os.Stdout, handler) - s.httpServer.Addr = fmt.Sprintf(":%d", s.erupeConfig.SignV2.Port) + s.httpServer.Addr = fmt.Sprintf(":%d", s.erupeConfig.API.Port) serveError := make(chan error, 1) go func() { @@ -76,7 +76,7 @@ func (s *Server) Start() error { } // Shutdown exits the server gracefully. -func (s *Server) Shutdown() { +func (s *APIServer) Shutdown() { s.logger.Debug("Shutting down") s.Lock() diff --git a/server/signv2server/dbutils.go b/server/api/dbutils.go similarity index 81% rename from server/signv2server/dbutils.go rename to server/api/dbutils.go index b2d5872bb..fba1bab5c 100644 --- a/server/signv2server/dbutils.go +++ b/server/api/dbutils.go @@ -1,4 +1,4 @@ -package signv2server +package api import ( "context" @@ -10,7 +10,7 @@ import ( "golang.org/x/crypto/bcrypt" ) -func (s *Server) createNewUser(ctx context.Context, username string, password string) (uint32, uint32, error) { +func (s *APIServer) createNewUser(ctx context.Context, username string, password string) (uint32, uint32, error) { // Create salted hash of user password passwordHash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) if err != nil { @@ -32,7 +32,7 @@ func (s *Server) createNewUser(ctx context.Context, username string, password st return id, rights, err } -func (s *Server) createLoginToken(ctx context.Context, uid uint32) (uint32, string, error) { +func (s *APIServer) createLoginToken(ctx context.Context, uid uint32) (uint32, string, error) { loginToken := token.Generate(16) var tid uint32 err := s.db.QueryRowContext(ctx, "INSERT INTO sign_sessions (user_id, token) VALUES ($1, $2) RETURNING id", uid, loginToken).Scan(&tid) @@ -42,7 +42,7 @@ func (s *Server) createLoginToken(ctx context.Context, uid uint32) (uint32, stri return tid, loginToken, nil } -func (s *Server) userIDFromToken(ctx context.Context, token string) (uint32, error) { +func (s *APIServer) userIDFromToken(ctx context.Context, token string) (uint32, error) { var userID uint32 err := s.db.QueryRowContext(ctx, "SELECT user_id FROM sign_sessions WHERE token = $1", token).Scan(&userID) if err == sql.ErrNoRows { @@ -53,7 +53,7 @@ func (s *Server) userIDFromToken(ctx context.Context, token string) (uint32, err return userID, nil } -func (s *Server) createCharacter(ctx context.Context, userID uint32) (Character, error) { +func (s *APIServer) createCharacter(ctx context.Context, userID uint32) (Character, error) { var character Character err := s.db.GetContext(ctx, &character, "SELECT id, name, is_female, weapon_type, hr, gr, last_login FROM characters WHERE is_new_character = true AND user_id = $1 LIMIT 1", @@ -78,7 +78,7 @@ func (s *Server) createCharacter(ctx context.Context, userID uint32) (Character, return character, err } -func (s *Server) deleteCharacter(ctx context.Context, userID uint32, charID uint32) error { +func (s *APIServer) deleteCharacter(ctx context.Context, userID uint32, charID uint32) error { var isNew bool err := s.db.QueryRow("SELECT is_new_character FROM characters WHERE id = $1", charID).Scan(&isNew) if err != nil { @@ -92,7 +92,7 @@ func (s *Server) deleteCharacter(ctx context.Context, userID uint32, charID uint return err } -func (s *Server) getCharactersForUser(ctx context.Context, uid uint32) ([]Character, error) { +func (s *APIServer) getCharactersForUser(ctx context.Context, uid uint32) ([]Character, error) { var characters []Character err := s.db.SelectContext( ctx, &characters, ` @@ -107,7 +107,7 @@ func (s *Server) getCharactersForUser(ctx context.Context, uid uint32) ([]Charac return characters, nil } -func (s *Server) getReturnExpiry(uid uint32) time.Time { +func (s *APIServer) getReturnExpiry(uid uint32) time.Time { var returnExpiry, lastLogin time.Time s.db.Get(&lastLogin, "SELECT COALESCE(last_login, now()) FROM users WHERE id=$1", uid) if time.Now().Add((time.Hour * 24) * -90).After(lastLogin) { @@ -124,7 +124,7 @@ func (s *Server) getReturnExpiry(uid uint32) time.Time { return returnExpiry } -func (s *Server) exportSave(ctx context.Context, uid uint32, cid uint32) (map[string]interface{}, error) { +func (s *APIServer) exportSave(ctx context.Context, uid uint32, cid uint32) (map[string]interface{}, error) { row := s.db.QueryRowxContext(ctx, "SELECT * FROM characters WHERE id=$1 AND user_id=$2", cid, uid) result := make(map[string]interface{}) err := row.MapScan(result) diff --git a/server/signv2server/endpoints.go b/server/api/endpoints.go similarity index 90% rename from server/signv2server/endpoints.go rename to server/api/endpoints.go index dd3864d2a..ef82cecdb 100644 --- a/server/signv2server/endpoints.go +++ b/server/api/endpoints.go @@ -1,4 +1,4 @@ -package signv2server +package api import ( "database/sql" @@ -30,9 +30,9 @@ const ( ) type LauncherResponse struct { - Banners []_config.SignV2Banner `json:"banners"` - Messages []_config.SignV2Message `json:"messages"` - Links []_config.SignV2Link `json:"links"` + Banners []_config.APISignBanner `json:"banners"` + Messages []_config.APISignMessage `json:"messages"` + Links []_config.APISignLink `json:"links"` } type User struct { @@ -75,7 +75,7 @@ type ExportData struct { Character map[string]interface{} `json:"character"` } -func (s *Server) newAuthData(userID uint32, userRights uint32, userTokenID uint32, userToken string, characters []Character) AuthData { +func (s *APIServer) newAuthData(userID uint32, userRights uint32, userTokenID uint32, userToken string, characters []Character) AuthData { resp := AuthData{ CurrentTS: uint32(channelserver.TimeAdjusted().Unix()), ExpiryTS: uint32(s.getReturnExpiry(userID).Unix()), @@ -86,7 +86,7 @@ func (s *Server) newAuthData(userID uint32, userRights uint32, userTokenID uint3 Token: userToken, }, Characters: characters, - PatchServer: s.erupeConfig.SignV2.PatchServer, + PatchServer: s.erupeConfig.API.PatchServer, Notices: []string{}, } if s.erupeConfig.DebugOptions.MaxLauncherHR { @@ -112,16 +112,16 @@ func (s *Server) newAuthData(userID uint32, userRights uint32, userTokenID uint3 return resp } -func (s *Server) Launcher(w http.ResponseWriter, r *http.Request) { +func (s *APIServer) Launcher(w http.ResponseWriter, r *http.Request) { var respData LauncherResponse - respData.Banners = s.erupeConfig.SignV2.Banners - respData.Messages = s.erupeConfig.SignV2.Messages - respData.Links = s.erupeConfig.SignV2.Links + respData.Banners = s.erupeConfig.API.Banners + respData.Messages = s.erupeConfig.API.Messages + respData.Links = s.erupeConfig.API.Links w.Header().Add("Content-Type", "application/json") json.NewEncoder(w).Encode(respData) } -func (s *Server) Login(w http.ResponseWriter, r *http.Request) { +func (s *APIServer) Login(w http.ResponseWriter, r *http.Request) { ctx := r.Context() var reqData struct { Username string `json:"username"` @@ -173,7 +173,7 @@ func (s *Server) Login(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(respData) } -func (s *Server) Register(w http.ResponseWriter, r *http.Request) { +func (s *APIServer) Register(w http.ResponseWriter, r *http.Request) { ctx := r.Context() var reqData struct { Username string `json:"username"` @@ -213,7 +213,7 @@ func (s *Server) Register(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(respData) } -func (s *Server) CreateCharacter(w http.ResponseWriter, r *http.Request) { +func (s *APIServer) CreateCharacter(w http.ResponseWriter, r *http.Request) { ctx := r.Context() var reqData struct { Token string `json:"token"` @@ -242,7 +242,7 @@ func (s *Server) CreateCharacter(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(character) } -func (s *Server) DeleteCharacter(w http.ResponseWriter, r *http.Request) { +func (s *APIServer) DeleteCharacter(w http.ResponseWriter, r *http.Request) { ctx := r.Context() var reqData struct { Token string `json:"token"` @@ -267,7 +267,7 @@ func (s *Server) DeleteCharacter(w http.ResponseWriter, r *http.Request) { json.NewEncoder(w).Encode(struct{}{}) } -func (s *Server) ExportSave(w http.ResponseWriter, r *http.Request) { +func (s *APIServer) ExportSave(w http.ResponseWriter, r *http.Request) { ctx := r.Context() var reqData struct { Token string `json:"token"` @@ -295,7 +295,7 @@ func (s *Server) ExportSave(w http.ResponseWriter, r *http.Request) { w.Header().Add("Content-Type", "application/json") json.NewEncoder(w).Encode(save) } -func (s *Server) ScreenShotGet(w http.ResponseWriter, r *http.Request) { +func (s *APIServer) ScreenShotGet(w http.ResponseWriter, r *http.Request) { // Get the 'id' parameter from the URL vars := mux.Vars(r) token := vars["id"] @@ -321,7 +321,7 @@ func (s *Server) ScreenShotGet(w http.ResponseWriter, r *http.Request) { return } } -func (s *Server) ScreenShot(w http.ResponseWriter, r *http.Request) { +func (s *APIServer) ScreenShot(w http.ResponseWriter, r *http.Request) { // Create a struct representing the XML result type Result struct { XMLName xml.Name `xml:"result"`