yuanshen/Yuanshen.Gameserver/Controllers/AvatarController.cs
wisedev a4b3b669a8 Use the named retcode and reason constants
Half the handlers were still answering with a bare 0 or -1 even though the whole
retcode table is generated. Values on the wire are unchanged, they just read
properly now.

Same for the item hint reasons. ActionReasonType is a generated enum and we were
redeclaring six of its members as private consts in four different files.
2026-09-04 11:21:12 +03:00

137 lines
5.2 KiB
C#

using Yuanshen.Gameserver.Controllers.Attributes;
using Yuanshen.Gameserver.Controllers.Result;
using Yuanshen.Gameserver.Database;
using Yuanshen.Gameserver.Game;
using Yuanshen.Gameserver.Network.Session;
using Yuanshen.Protocol;
using Microsoft.Extensions.Logging;
namespace Yuanshen.Gameserver.Controllers;
[NetController]
internal sealed class AvatarController : ControllerBase
{
[NetCommand(CmdType.SetUpAvatarTeamReq)]
public async ValueTask<IResult> OnSetUpAvatarTeamReq(Player player, SceneManager sceneManager, PlayerPersistence persistence)
{
SetUpAvatarTeamReq req = Packet!.DecodeBody<SetUpAvatarTeamReq>();
if (req.AvatarTeamGuidList.Count == 0)
return Response(CmdType.SetUpAvatarTeamRsp, new SetUpAvatarTeamRsp { Retcode = Retcode.RET_FAIL });
await sceneManager.SetupTeamAsync(req.TeamId, req.AvatarTeamGuidList, req.CurAvatarGuid);
await persistence.SaveAsync();
SetUpAvatarTeamRsp rsp = new()
{
Retcode = Retcode.RET_SUCC,
TeamId = req.TeamId,
CurAvatarGuid = player.CurrentAvatarGuid
};
rsp.AvatarTeamGuidList.AddRange(req.AvatarTeamGuidList);
return Response(CmdType.SetUpAvatarTeamRsp, rsp);
}
[NetCommand(CmdType.ChangeAvatarReq)]
public async ValueTask<IResult> OnChangeAvatarReq(SceneManager sceneManager, PlayerPersistence persistence)
{
ChangeAvatarReq req = Packet!.DecodeBody<ChangeAvatarReq>();
await sceneManager.ChangeAvatarAsync(req.Guid);
await persistence.SaveAsync();
return Response(CmdType.ChangeAvatarRsp, new ChangeAvatarRsp
{
Retcode = Retcode.RET_SUCC,
CurrGuid = req.Guid,
SkillId = req.SkillId
});
}
private static bool OnScene(Player player, GameAvatar avatar)
=> player.TeamAvatarGuids.Contains(avatar.Guid);
[NetCommand(CmdType.WearEquipReq)]
public async ValueTask<IResult> OnWearEquipReq(NetSession session, Player player, SceneManager sceneManager, PlayerPersistence persistence, ILogger<AvatarController> logger)
{
WearEquipReq req = Packet!.DecodeBody<WearEquipReq>();
GameAvatar? avatar = player.FindAvatar(req.AvatarGuid);
GameWeapon? weapon = player.FindWeapon(req.EquipGuid);
GameReliquary? reliquary = player.FindReliquary(req.EquipGuid);
logger.LogDebug("WearEquip avatarGuid={a} equipGuid={e} -> avatar={av} weapon={w} reliquary={r}",
req.AvatarGuid, req.EquipGuid,
avatar is null ? "NOT FOUND" : avatar.AvatarId.ToString(),
weapon is null ? "-" : weapon.ItemId.ToString(),
reliquary is null ? "-" : reliquary.ItemId.ToString());
if (avatar is not null && weapon is not null)
{
avatar.WeaponGuid = weapon.Guid;
await session.NotifyAsync(CmdType.AvatarEquipChangeNotify, new AvatarEquipChangeNotify
{
AvatarGuid = avatar.Guid,
EquipType = 6,
ItemId = weapon.ItemId,
EquipGuid = weapon.Guid,
Weapon = weapon.AsSceneWeapon(OnScene(player, avatar) ? avatar.WeaponEntityId : 0)
});
}
else if (avatar is not null && reliquary is not null)
{
avatar.ReliquaryGuids[reliquary.EquipType] = reliquary.Guid;
await session.NotifyAsync(CmdType.AvatarEquipChangeNotify, new AvatarEquipChangeNotify
{
AvatarGuid = avatar.Guid,
EquipType = reliquary.EquipType,
ItemId = reliquary.ItemId,
EquipGuid = reliquary.Guid,
Reliquary = reliquary.AsSceneReliquary()
});
}
if (avatar is not null && player.TeamAvatarGuids.Contains(avatar.Guid))
await session.NotifyAsync(CmdType.SceneTeamUpdateNotify, sceneManager.BuildSceneTeamUpdate());
if (avatar is not null)
await persistence.SaveAsync();
return Response(CmdType.WearEquipRsp, new WearEquipRsp
{
Retcode = Retcode.RET_SUCC,
AvatarGuid = req.AvatarGuid,
EquipGuid = req.EquipGuid
});
}
[NetCommand(CmdType.AvatarWearFlycloakReq)]
public async ValueTask<IResult> OnAvatarWearFlycloakReq(Player player, NetSession session, PlayerPersistence persistence)
{
AvatarWearFlycloakReq req = Packet!.DecodeBody<AvatarWearFlycloakReq>();
GameAvatar? avatar = player.Avatars.FirstOrDefault(candidate => candidate.Guid == req.AvatarGuid);
if (avatar is null)
return Response(CmdType.AvatarWearFlycloakRsp, new AvatarWearFlycloakRsp { Retcode = Retcode.RET_AVATAR_ID_ERROR });
avatar.FlycloakId = req.FlycloakId;
await session.NotifyAsync(CmdType.AvatarFlycloakChangeNotify, new AvatarFlycloakChangeNotify
{
AvatarGuid = req.AvatarGuid,
FlycloakId = req.FlycloakId
});
await persistence.SaveAsync();
return Response(CmdType.AvatarWearFlycloakRsp, new AvatarWearFlycloakRsp
{
Retcode = Retcode.RET_SUCC,
AvatarGuid = req.AvatarGuid,
FlycloakId = req.FlycloakId
});
}
}