一些检测仍在等待运行
Docs Build / build-and-deploy (push) Waiting to run
- 移除 ConfigManager 配置管理器类 - 移除 GameManager 全局单例管理器类 - 移除 NetworkManager 网络连接管理器类 - 移除 CharacterData 和 ItemData 数据模型类 - 移除 BagScene、BattleScene、LobbyScene 等场景脚本 - 移除 EncounterBubble 和 EventFeedPanel UI组件脚本 - 更新代理邀请文档中的服务器连接方式 - 更新同步状态表格中的代理任务分配信息 - 添加 MiMo 任务完成总结和审查修复记录
177 行
5.1 KiB
Go
177 行
5.1 KiB
Go
// Package modules - 世界Boss系统模块
|
||
// 对齐GDD-33 世界Boss与大型PVE协作机制
|
||
package modules
|
||
|
||
import (
|
||
"context"
|
||
"database/sql"
|
||
"encoding/json"
|
||
"time"
|
||
|
||
"github.com/heroiclabs/nakama-common/runtime"
|
||
)
|
||
|
||
// RegisterWorldBoss 注册世界Boss相关 RPC。
|
||
func RegisterWorldBoss(initializer runtime.Initializer) error {
|
||
rpcs := map[string]func(context.Context, runtime.Logger, *sql.DB, runtime.NakamaModule, string) (string, error){
|
||
"WorldBossService/GetActiveBosses": getActiveBosses,
|
||
"WorldBossService/JoinBossFight": joinBossFight,
|
||
"WorldBossService/GetBossRanking": getBossRanking,
|
||
}
|
||
for path, fn := range rpcs {
|
||
if err := initializer.RegisterRpc(path, fn); err != nil {
|
||
return err
|
||
}
|
||
}
|
||
return nil
|
||
}
|
||
|
||
type getActiveBossesReq struct {
|
||
WorldTier int32 `json:"world_tier"`
|
||
}
|
||
|
||
type joinBossFightReq struct {
|
||
BossID string `json:"boss_id"`
|
||
}
|
||
|
||
type getBossRankingReq struct {
|
||
BossID string `json:"boss_id"`
|
||
}
|
||
|
||
type worldBossData struct {
|
||
ID string `json:"id"`
|
||
Name string `json:"name"`
|
||
WorldTier int32 `json:"world_tier"`
|
||
RealmTier int32 `json:"realm_tier"`
|
||
MaxHP int64 `json:"max_hp"`
|
||
CurrentHP int64 `json:"current_hp"`
|
||
Attack int32 `json:"attack"`
|
||
Defense int32 `json:"defense"`
|
||
Elements interface{} `json:"elements"`
|
||
SpawnTime time.Time `json:"spawn_time"`
|
||
DespawnTime time.Time `json:"despawn_time"`
|
||
Participants int32 `json:"participants"`
|
||
Status string `json:"status"` // spawning/active/defeated/despawned
|
||
}
|
||
|
||
type bossRankingData struct {
|
||
BossID string `json:"boss_id"`
|
||
CharacterID string `json:"character_id"`
|
||
CharName string `json:"char_name"`
|
||
DamageDealt int64 `json:"damage_dealt"`
|
||
Rank int32 `json:"rank"`
|
||
}
|
||
|
||
// 世界Boss模板
|
||
var worldBossTemplates = map[string]worldBossData{
|
||
"ancient_dragon_boss": {
|
||
ID: "ancient_dragon_boss", Name: "远古巨龙", WorldTier: 4, RealmTier: 6,
|
||
MaxHP: 5000000, Attack: 800, Defense: 500,
|
||
Elements: []string{"fire", "lightning"},
|
||
Status: "spawning",
|
||
},
|
||
"chaos_eye": {
|
||
ID: "chaos_eye", Name: "混沌之眼", WorldTier: 5, RealmTier: 8,
|
||
MaxHP: 20000000, Attack: 3000, Defense: 2000,
|
||
Elements: []string{"chaos"},
|
||
Status: "spawning",
|
||
},
|
||
"old_god_avatar": {
|
||
ID: "old_god_avatar", Name: "旧神化身", WorldTier: 6, RealmTier: 9,
|
||
MaxHP: 100000000, Attack: 10000, Defense: 8000,
|
||
Elements: []string{"chaos", "void"},
|
||
Status: "spawning",
|
||
},
|
||
}
|
||
|
||
func getActiveBosses(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, payload string) (string, error) {
|
||
traceID := newTraceID()
|
||
|
||
var req getActiveBossesReq
|
||
if err := json.Unmarshal([]byte(payload), &req); err != nil {
|
||
return errResp(2001, "invalid payload", traceID)
|
||
}
|
||
|
||
var bosses []worldBossData
|
||
for _, boss := range worldBossTemplates {
|
||
if boss.WorldTier == req.WorldTier || req.WorldTier == 0 {
|
||
bosses = append(bosses, boss)
|
||
}
|
||
}
|
||
|
||
return okResp(map[string]interface{}{
|
||
"bosses": bosses,
|
||
"count": len(bosses),
|
||
}, traceID)
|
||
}
|
||
|
||
func joinBossFight(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, payload string) (string, error) {
|
||
traceID := newTraceID()
|
||
uid := userIDFromCtx(ctx)
|
||
if uid == "" {
|
||
return errResp(1001, "missing token", traceID)
|
||
}
|
||
|
||
var req joinBossFightReq
|
||
if err := json.Unmarshal([]byte(payload), &req); err != nil {
|
||
return errResp(2001, "invalid payload", traceID)
|
||
}
|
||
|
||
// 获取角色信息
|
||
var charID string
|
||
var charName string
|
||
var realmTier int32
|
||
err := hhdbPool.QueryRow(ctx, `
|
||
SELECT id, name, realm_tier FROM characters WHERE player_id = $1 AND status = 'active'
|
||
ORDER BY created_at DESC LIMIT 1
|
||
`, uid).Scan(&charID, &charName, &realmTier)
|
||
if err != nil {
|
||
return errResp(4002, "character not found", traceID)
|
||
}
|
||
|
||
// 检查Boss是否存在
|
||
boss, ok := worldBossTemplates[req.BossID]
|
||
if !ok {
|
||
return errResp(8601, "boss not found", traceID)
|
||
}
|
||
|
||
// 检查境界要求
|
||
if realmTier < boss.RealmTier-2 {
|
||
return errResp(8602, "realm too low for this boss", traceID)
|
||
}
|
||
|
||
// 加入Boss战(简化版)
|
||
logger.Info("Join boss fight: boss=%s player=%s", req.BossID, charName)
|
||
|
||
return okResp(map[string]interface{}{
|
||
"success": true,
|
||
"boss_id": req.BossID,
|
||
"boss_name": boss.Name,
|
||
"character_id": charID,
|
||
"character_name": charName,
|
||
"message": "已加入Boss战",
|
||
}, traceID)
|
||
}
|
||
|
||
func getBossRanking(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, payload string) (string, error) {
|
||
traceID := newTraceID()
|
||
|
||
var req getBossRankingReq
|
||
if err := json.Unmarshal([]byte(payload), &req); err != nil {
|
||
return errResp(2001, "invalid payload", traceID)
|
||
}
|
||
|
||
// 模拟排行榜
|
||
ranking := []bossRankingData{
|
||
{BossID: req.BossID, CharacterID: "char_1", CharName: "仙尊", DamageDealt: 1000000, Rank: 1},
|
||
{BossID: req.BossID, CharacterID: "char_2", CharName: "剑圣", DamageDealt: 800000, Rank: 2},
|
||
{BossID: req.BossID, CharacterID: "char_3", CharName: "魔尊", DamageDealt: 600000, Rank: 3},
|
||
}
|
||
|
||
return okResp(map[string]interface{}{
|
||
"boss_id": req.BossID,
|
||
"ranking": ranking,
|
||
"count": len(ranking),
|
||
}, traceID)
|
||
}
|