package routes import ( "dk/internal/actions" "dk/internal/components" "dk/internal/database" "dk/internal/models/towns" "dk/internal/models/users" "slices" "strconv" sushi "git.sharkk.net/Sharkk/Sushi" "git.sharkk.net/Sharkk/Sushi/password" ) func Index(ctx sushi.Ctx) { if !ctx.IsAuthenticated() { components.RenderPage(ctx, "", "intro.html", nil) return } user := ctx.GetCurrentUser().(*users.User) switch user.Currently { case "In Town": ctx.Redirect("/town") case "Exploring": ctx.Redirect("/explore") case "Fighting": ctx.Redirect("/fight") default: ctx.Redirect("/explore") } } func Move(ctx sushi.Ctx) { sess := ctx.GetCurrentSession() user := ctx.GetCurrentUser().(*users.User) if user.Currently == "Fighting" { sess.SetFlash("error", "You can't just run from a fight!") ctx.Redirect("/fight") return } dir, err := strconv.Atoi(string(ctx.PostArgs().Peek("direction"))) if err != nil { ctx.SendError(400, "move form parsing error") return } currently, newX, newY, err := actions.Move(user, actions.Direction(dir)) if err != nil { ctx.SendError(400, "move error: "+err.Error()) return } updateData := map[string]any{ "currently": currently, "x": newX, "y": newY, } if currently == "Fighting" { updateData["fight_id"] = user.FightID } err = database.Transaction(func() error { return database.Update("users", updateData, "id", user.ID) }) if err != nil { ctx.SendError(500, "failed to update user position") return } switch currently { case "In Town": ctx.Redirect("/town") case "Fighting": ctx.Redirect("/fight") default: ctx.Redirect("/explore") } } func Explore(ctx sushi.Ctx) { user := ctx.GetCurrentUser().(*users.User) if user.Currently != "Exploring" { ctx.Redirect("/") return } components.RenderPage(ctx, "", "explore.html", nil) } func Teleport(ctx sushi.Ctx) { sess := ctx.GetCurrentSession() id := ctx.Param("to").Int() town, err := towns.Find(id) if err != nil { sess.SetFlash("error", "Failed to teleport. Unknown town.") ctx.Redirect("/") return } user := ctx.GetCurrentUser().(*users.User) if !slices.Contains(user.GetTownIDs(), id) { sess.SetFlash("error", "You don't have a map to "+town.Name+".") ctx.Redirect("/") return } if user.TP < town.TPCost { sess.SetFlash("error", "You don't have enough TP to teleport to "+town.Name+".") ctx.Redirect("/") return } err = database.Transaction(func() error { return database.Update("users", map[string]any{ "tp": user.TP - town.TPCost, "x": town.X, "y": town.Y, "currently": "In Town", }, "id", user.ID) }) if err != nil { sess.SetFlash("error", "Failed to complete teleport.") ctx.Redirect("/") return } sess.SetFlash("success", "You teleported to "+town.Name+" successfully!") ctx.Redirect("/town") } func ShowChangePassword(ctx sushi.Ctx) { components.RenderPage(ctx, "Change Password", "changepassword.html", nil) } func ChangePassword(ctx sushi.Ctx) { sess := ctx.GetCurrentSession() user := ctx.GetCurrentUser().(*users.User) currentPassword := ctx.Form("p").String() newPassword := ctx.Form("p2").String() confirmPassword := ctx.Form("p3").String() // Validate inputs if currentPassword == "" || newPassword == "" || confirmPassword == "" { sess.SetFlash("error", "All fields are required") ctx.Redirect("/change-password") return } if len(newPassword) < 6 { sess.SetFlash("error", "New password must be at least 6 characters") ctx.Redirect("/change-password") return } if newPassword != confirmPassword { sess.SetFlash("error", "New passwords do not match") ctx.Redirect("/change-password") return } // Verify current password isValid, err := password.VerifyPassword(currentPassword, user.Password) if err != nil { sess.SetFlash("error", "Password verification failed") ctx.Redirect("/change-password") return } if !isValid { sess.SetFlash("error", "Current password is incorrect") ctx.Redirect("/change-password") return } // Update password err = database.Transaction(func() error { return database.Update("users", map[string]any{ "password": password.HashPassword(newPassword), }, "id", user.ID) }) if err != nil { sess.SetFlash("error", "Failed to update password") ctx.Redirect("/change-password") return } sess.SetFlash("success", "Password changed successfully!") ctx.Redirect("/") }