mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-03-22 07:32:32 +01:00
Merge pull request #101 from rockisch/signv2-changes
Implement final changes for custom launcher
This commit is contained in:
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
"erupe-ce/common/byteframe"
|
||||
ps "erupe-ce/common/pascalstring"
|
||||
"erupe-ce/config"
|
||||
_config "erupe-ce/config"
|
||||
"erupe-ce/network/binpacket"
|
||||
"erupe-ce/network/mhfpacket"
|
||||
"erupe-ce/server/discordbot"
|
||||
|
||||
@@ -122,3 +122,13 @@ func (s *Server) getReturnExpiry(uid uint32) time.Time {
|
||||
s.db.Exec("UPDATE users SET last_login=$1 WHERE id=$2", time.Now(), uid)
|
||||
return returnExpiry
|
||||
}
|
||||
|
||||
func (s *Server) 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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -4,25 +4,25 @@ import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
_config "erupe-ce/config"
|
||||
"erupe-ce/server/channelserver"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/lib/pq"
|
||||
"go.uber.org/zap"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
type LauncherMessage struct {
|
||||
Message string `json:"message"`
|
||||
Date int64 `json:"date"`
|
||||
Link string `json:"link"`
|
||||
}
|
||||
const (
|
||||
NotificationDefault = iota
|
||||
NotificationNew
|
||||
)
|
||||
|
||||
type LauncherResponse struct {
|
||||
Important []LauncherMessage `json:"important"`
|
||||
Normal []LauncherMessage `json:"normal"`
|
||||
Banners []_config.SignV2Banner `json:"banners"`
|
||||
Messages []_config.SignV2Message `json:"messages"`
|
||||
Links []_config.SignV2Link `json:"links"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
@@ -37,7 +37,7 @@ type Character struct {
|
||||
Weapon uint32 `json:"weapon" db:"weapon_type"`
|
||||
HR uint32 `json:"hr" db:"hrp"`
|
||||
GR uint32 `json:"gr"`
|
||||
LastLogin int64 `json:"lastLogin" db:"last_login"`
|
||||
LastLogin int32 `json:"lastLogin" db:"last_login"`
|
||||
}
|
||||
|
||||
type MezFes struct {
|
||||
@@ -53,10 +53,15 @@ type AuthData struct {
|
||||
CurrentTS uint32 `json:"currentTs"`
|
||||
ExpiryTS uint32 `json:"expiryTs"`
|
||||
EntranceCount uint32 `json:"entranceCount"`
|
||||
Notifications []string `json:"notifications"`
|
||||
Notices []string `json:"notices"`
|
||||
User User `json:"user"`
|
||||
Characters []Character `json:"characters"`
|
||||
MezFes *MezFes `json:"mezFes"`
|
||||
PatchServer string `json:"patchServer"`
|
||||
}
|
||||
|
||||
type ExportData struct {
|
||||
Character map[string]interface{} `json:"character"`
|
||||
}
|
||||
|
||||
func (s *Server) newAuthData(userID uint32, userRights uint32, userToken string, characters []Character) AuthData {
|
||||
@@ -68,7 +73,14 @@ func (s *Server) newAuthData(userID uint32, userRights uint32, userToken string,
|
||||
Rights: userRights,
|
||||
Token: userToken,
|
||||
},
|
||||
Characters: characters,
|
||||
Characters: characters,
|
||||
PatchServer: s.erupeConfig.SignV2.PatchServer,
|
||||
Notices: []string{},
|
||||
}
|
||||
if s.erupeConfig.DevModeOptions.MaxLauncherHR {
|
||||
for i := range resp.Characters {
|
||||
resp.Characters[i].HR = 7
|
||||
}
|
||||
}
|
||||
if s.erupeConfig.DevModeOptions.MezFesEvent {
|
||||
stalls := []uint32{10, 3, 6, 9, 4, 8, 5, 7}
|
||||
@@ -85,38 +97,16 @@ func (s *Server) newAuthData(userID uint32, userRights uint32, userToken string,
|
||||
}
|
||||
}
|
||||
if !s.erupeConfig.HideLoginNotice {
|
||||
resp.Notifications = append(resp.Notifications, strings.Join(s.erupeConfig.LoginNotices[:], "<PAGE>"))
|
||||
resp.Notices = append(resp.Notices, strings.Join(s.erupeConfig.LoginNotices[:], "<PAGE>"))
|
||||
}
|
||||
return resp
|
||||
}
|
||||
|
||||
func (s *Server) Launcher(w http.ResponseWriter, r *http.Request) {
|
||||
var respData LauncherResponse
|
||||
respData.Important = []LauncherMessage{
|
||||
{
|
||||
Message: "Server Update 9 Released!",
|
||||
Date: time.Date(2022, 8, 2, 0, 0, 0, 0, time.UTC).Unix(),
|
||||
Link: "https://discord.com/channels/368424389416583169/929509970624532511/1003985850255818762",
|
||||
},
|
||||
{
|
||||
Message: "Eng 2.0 & Ravi Patch Released!",
|
||||
Date: time.Date(2022, 5, 3, 0, 0, 0, 0, time.UTC).Unix(),
|
||||
Link: "https://discord.com/channels/368424389416583169/929509970624532511/969305400795078656",
|
||||
},
|
||||
{
|
||||
Message: "Launcher Patch V1.0 Released!",
|
||||
Date: time.Date(2022, 4, 24, 0, 0, 0, 0, time.UTC).Unix(),
|
||||
Link: "https://discord.com/channels/368424389416583169/929509970624532511/969286397301248050",
|
||||
},
|
||||
}
|
||||
respData.Normal = []LauncherMessage{
|
||||
{
|
||||
Message: "Join the community Discord for updates!",
|
||||
Date: time.Date(2022, 4, 24, 0, 0, 0, 0, time.UTC).Unix(),
|
||||
Link: "https://discord.gg/CFnzbhQ",
|
||||
},
|
||||
}
|
||||
w.WriteHeader(200)
|
||||
respData.Banners = s.erupeConfig.SignV2.Banners
|
||||
respData.Messages = s.erupeConfig.SignV2.Messages
|
||||
respData.Links = s.erupeConfig.SignV2.Links
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(respData)
|
||||
}
|
||||
@@ -130,7 +120,6 @@ func (s *Server) Login(w http.ResponseWriter, r *http.Request) {
|
||||
if err := json.NewDecoder(r.Body).Decode(&reqData); err != nil {
|
||||
s.logger.Error("JSON decode error", zap.Error(err))
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte("Invalid data received"))
|
||||
return
|
||||
}
|
||||
var (
|
||||
@@ -141,7 +130,7 @@ func (s *Server) Login(w http.ResponseWriter, r *http.Request) {
|
||||
err := s.db.QueryRow("SELECT id, password, rights FROM users WHERE username = $1", reqData.Username).Scan(&userID, &password, &userRights)
|
||||
if err == sql.ErrNoRows {
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte("Username does not exist"))
|
||||
w.Write([]byte("username-error"))
|
||||
return
|
||||
} else if err != nil {
|
||||
s.logger.Warn("SQL query error", zap.Error(err))
|
||||
@@ -150,7 +139,7 @@ func (s *Server) Login(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
if bcrypt.CompareHashAndPassword([]byte(password), []byte(reqData.Password)) != nil {
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte("Your password is incorrect"))
|
||||
w.Write([]byte("password-error"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -166,8 +155,10 @@ func (s *Server) Login(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(500)
|
||||
return
|
||||
}
|
||||
if characters == nil {
|
||||
characters = []Character{}
|
||||
}
|
||||
respData := s.newAuthData(userID, userRights, userToken, characters)
|
||||
w.WriteHeader(200)
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(respData)
|
||||
}
|
||||
@@ -181,7 +172,10 @@ func (s *Server) Register(w http.ResponseWriter, r *http.Request) {
|
||||
if err := json.NewDecoder(r.Body).Decode(&reqData); err != nil {
|
||||
s.logger.Error("JSON decode error", zap.Error(err))
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte("Invalid data received"))
|
||||
return
|
||||
}
|
||||
if reqData.Username == "" || reqData.Password == "" {
|
||||
w.WriteHeader(400)
|
||||
return
|
||||
}
|
||||
s.logger.Info("Creating account", zap.String("username", reqData.Username))
|
||||
@@ -190,7 +184,7 @@ func (s *Server) Register(w http.ResponseWriter, r *http.Request) {
|
||||
var pqErr *pq.Error
|
||||
if errors.As(err, &pqErr) && pqErr.Constraint == "users_username_key" {
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte("User already exists"))
|
||||
w.Write([]byte("username-exists-error"))
|
||||
return
|
||||
}
|
||||
s.logger.Error("Error checking user", zap.Error(err), zap.String("username", reqData.Username))
|
||||
@@ -205,6 +199,7 @@ func (s *Server) Register(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
respData := s.newAuthData(userID, userRights, userToken, []Character{})
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(respData)
|
||||
}
|
||||
|
||||
@@ -216,7 +211,6 @@ func (s *Server) CreateCharacter(w http.ResponseWriter, r *http.Request) {
|
||||
if err := json.NewDecoder(r.Body).Decode(&reqData); err != nil {
|
||||
s.logger.Error("JSON decode error", zap.Error(err))
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte("Invalid data received"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -231,6 +225,10 @@ func (s *Server) CreateCharacter(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(500)
|
||||
return
|
||||
}
|
||||
if s.erupeConfig.DevModeOptions.MaxLauncherHR {
|
||||
character.HR = 7
|
||||
}
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(character)
|
||||
}
|
||||
|
||||
@@ -243,7 +241,6 @@ func (s *Server) DeleteCharacter(w http.ResponseWriter, r *http.Request) {
|
||||
if err := json.NewDecoder(r.Body).Decode(&reqData); err != nil {
|
||||
s.logger.Error("JSON decode error", zap.Error(err))
|
||||
w.WriteHeader(400)
|
||||
w.Write([]byte("Invalid data received"))
|
||||
return
|
||||
}
|
||||
userID, err := s.userIDFromToken(ctx, reqData.Token)
|
||||
@@ -256,5 +253,35 @@ func (s *Server) DeleteCharacter(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(500)
|
||||
return
|
||||
}
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(struct{}{})
|
||||
}
|
||||
|
||||
func (s *Server) ExportSave(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
var reqData struct {
|
||||
Token string `json:"token"`
|
||||
CharID uint32 `json:"charId"`
|
||||
}
|
||||
if err := json.NewDecoder(r.Body).Decode(&reqData); err != nil {
|
||||
s.logger.Error("JSON decode error", zap.Error(err))
|
||||
w.WriteHeader(400)
|
||||
return
|
||||
}
|
||||
userID, err := s.userIDFromToken(ctx, reqData.Token)
|
||||
if err != nil {
|
||||
w.WriteHeader(401)
|
||||
return
|
||||
}
|
||||
character, err := s.exportSave(ctx, userID, reqData.CharID)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to export save", zap.Error(err), zap.String("token", reqData.Token), zap.Uint32("charID", reqData.CharID))
|
||||
w.WriteHeader(500)
|
||||
return
|
||||
}
|
||||
save := ExportData{
|
||||
Character: character,
|
||||
}
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(save)
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ func (s *Server) Start() error {
|
||||
r.HandleFunc("/register", s.Register)
|
||||
r.HandleFunc("/character/create", s.CreateCharacter)
|
||||
r.HandleFunc("/character/delete", s.DeleteCharacter)
|
||||
r.HandleFunc("/character/export", s.ExportSave)
|
||||
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)
|
||||
|
||||
Reference in New Issue
Block a user