Skip to content

Commit

Permalink
Handle events from Grpc stream (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
SzymonKaminski authored and eXpl0it3r committed May 29, 2024
1 parent 2a9920e commit 50c4411
Show file tree
Hide file tree
Showing 8 changed files with 412 additions and 6 deletions.
8 changes: 7 additions & 1 deletion UdpHosts/GameServer/Data/HardcodedCharacterData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace GameServer.Data;

public static class HardcodedCharacterData
{
public static string ArmyTag = "[ARMY]";
public static string ArmyTag = "ARMY";
public static ulong ArmyGUID = 1u;
public static uint SelectedLoadout = 184538131;
public static byte Level = 45;
Expand All @@ -27,6 +27,9 @@ public static class HardcodedCharacterData
Race = (uint)CharacterRace.Human,
TitleId = 135,
CurrentBattleframeSDBId = 76331,
ArmyTag = ArmyTag,
ArmyGuid = ArmyGUID,
ArmyIsOfficer = true,
},
CharacterVisuals = new BasicCharacterVisuals()
{
Expand Down Expand Up @@ -951,6 +954,9 @@ public class BasicCharacterInfo
public uint Race { get; set; }
public ushort TitleId { get; set; }
public uint CurrentBattleframeSDBId { get; set; }
public string ArmyTag { get; set; }
public ulong ArmyGuid { get; set; }
public bool ArmyIsOfficer { get; set; }
}

public class BasicCharacterVisuals
Expand Down
34 changes: 31 additions & 3 deletions UdpHosts/GameServer/Entities/Character/CharacterEntity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
using GameServer.Data.SDB;
using GameServer.Data.SDB.Records.dbstats;
using GameServer.Enums;
using GameServer.Test;
using GrpcGameServerAPIClient;

namespace GameServer.Entities.Character;
Expand Down Expand Up @@ -99,6 +100,8 @@ public CharacterEntity(IShard shard, ulong eid)
public ulong CurrentPermissionsValue => GetCurrentPermissionsValue();

public StaticInfoData StaticInfo { get; set; }
public ulong ArmyGUID { get; set; }
public byte ArmyIsOfficer { get; set; }
public CharacterStateData CharacterState { get; set; }
public HostilityInfoData HostilityInfo { get; set; }
public MaxVital MaxShields { get; set; }
Expand Down Expand Up @@ -372,6 +375,9 @@ public void LoadRemote(CharacterAndBattleframeVisuals remoteData)
Race = (byte)remoteData.CharacterInfo.Race,
TitleId = (ushort)remoteData.CharacterInfo.TitleId,
CurrentBattleframeSDBId = remoteData.CharacterInfo.CurrentBattleframeSDBId,
ArmyGuid = remoteData.CharacterInfo.ArmyGuid,
ArmyTag = remoteData.CharacterInfo.ArmyTag,
ArmyIsOfficer = remoteData.CharacterInfo.ArmyIsOfficer,
},
CharacterVisuals = new Data.BasicCharacterVisuals()
{
Expand Down Expand Up @@ -439,8 +445,11 @@ public void Load(BasicCharacterData data)
MorphWeights = Array.Empty<HalfFloat>(),
Overlays = Array.Empty<VisualsOverlayBlock>()
},
ArmyTag = HardcodedCharacterData.ArmyTag
ArmyTag = DataUtils.FormatArmyTag(info.ArmyTag)
});

SetArmyGUID(info.ArmyGuid);
SetArmyIsOfficer((byte)(info.ArmyIsOfficer ? 1 : 0));
}

public void ApplyLoadout(CharacterLoadout loadout)
Expand Down Expand Up @@ -694,6 +703,25 @@ public void SetStaticInfo(StaticInfoData value)
}
}

public void SetArmyGUID(ulong value)
{
ArmyGUID = value;
Character_ObserverView.ArmyGUIDProp = ArmyGUID;
if (Character_BaseController != null)
{
Character_BaseController.ArmyGUIDProp = ArmyGUID;
}
}

public void SetArmyIsOfficer(byte value)
{
ArmyIsOfficer = value;
if (Character_BaseController != null)
{
Character_BaseController.ArmyIsOfficerProp = ArmyIsOfficer;
}
}

public void SetCurrentEquipment(EquipmentData value)
{
CurrentEquipment = value;
Expand Down Expand Up @@ -1102,8 +1130,8 @@ private void InitControllers()
SinFlagsPrivateProp = 0,
SinFactionsAcquiredByProp = null,
SinTeamsAcquiredByProp = null,
ArmyGUIDProp = HardcodedCharacterData.ArmyGUID,
ArmyIsOfficerProp = 0,
ArmyGUIDProp = ArmyGUID,
ArmyIsOfficerProp = ArmyIsOfficer,
EncounterPartyTupleProp = null,
DockedParamsProp = DockedParams,
LookAtTargetProp = null,
Expand Down
197 changes: 197 additions & 0 deletions UdpHosts/GameServer/GRPC/EventHandlers/ArmyEventHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
using AeroMessages.GSS.V66.Character.Event;
using GameServer.Test;
using Google.Protobuf.Collections;
using GrpcGameServerAPIClient;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace GameServer.GRPC.EventHandlers;

public static class ArmyEventHandler
{
private static readonly JsonSerializerOptions SerializerOptions
= new() { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull };

public static void HandleEvent(ArmyApplicationApproved e, IDictionary<uint, INetworkPlayer> clients)
{
SendMessageToCharacter(clients, e.CharacterGuid, "army_application_approve", e.InitiatorName);
}

public static void HandleEvent(ArmyApplicationReceived e, IDictionary<uint, INetworkPlayer> clients)
{
SendMessageToAuthorizedArmyMembers(clients, e.ArmyMemberGuids, "army_application", e.InitiatorName);
}

public static void HandleEvent(ArmyApplicationRejected e, IDictionary<uint, INetworkPlayer> clients)
{
SendMessageToCharacter(clients, e.CharacterGuid, "army_application_reject", e.InitiatorName);
}

public static void HandleEvent(ArmyApplicationsUpdated e, IDictionary<uint, INetworkPlayer> clients)
{
SendMessageToAuthorizedArmyMembers(clients, e.ArmyMemberGuids, "army_applications_change");
}

public static void HandleEvent(ArmyIdChanged e, IDictionary<uint, INetworkPlayer> clients)
{
var player = clients.Values.FirstOrDefault(p => p.CharacterId + 0xFE == e.CharacterGuid);

if (player == null)
{
return;
}

var playerEntity = player.CharacterEntity;

var staticInfo = playerEntity.StaticInfo;
staticInfo.ArmyTag = DataUtils.FormatArmyTag(e.ArmyTag);

playerEntity.SetStaticInfo(staticInfo);

playerEntity.Character_BaseController.ArmyGUIDProp = e.ArmyGuid;
playerEntity.Character_BaseController.ArmyIsOfficerProp = (byte)(e.IsOfficer ? 1 : 0);
}

public static void HandleEvent(ArmyInfoUpdated e, IDictionary<uint, INetworkPlayer> clients)
{
SendMessageToAllArmyMembers(clients, e.ArmyGuid, "army_info_change");
}

public static void HandleEvent(ArmyInviteApproved e, IDictionary<uint, INetworkPlayer> clients)
{
SendMessageToAllArmyMembers(clients, e.ArmyGuid, "army_invite_approve", e.InitiatorName);
}

public static void HandleEvent(ArmyInviteReceived e, IDictionary<uint, INetworkPlayer> clients)
{
var player = clients.Values.FirstOrDefault(p => p.CharacterId + 0xFE == e.CharacterGuid);

if (player == null)
{
return;
}

var message = new ArmyMessage
{
message_type = "army_invite",
initiator = e.InitiatorName,
army = new Army { army_guid = e.ArmyGuid, name = e.ArmyName },
application = new Application { id = e.Id, message = e.Message }
};

string json = JsonSerializer.Serialize(message, SerializerOptions);

var msg = new ReceivedWebUIMessage() { Message = json };

player.NetChannels[ChannelType.ReliableGss].SendIAero(msg, player.CharacterId);
}

public static void HandleEvent(ArmyInviteRejected e, IDictionary<uint, INetworkPlayer> clients)
{
SendMessageToAuthorizedArmyMembers(clients, e.ArmyMemberGuids, "army_invite_reject", e.InitiatorName);
}

public static void HandleEvent(ArmyMembersUpdated e, IDictionary<uint, INetworkPlayer> clients)
{
SendMessageToAllArmyMembers(clients, e.ArmyGuid, "army_characters_change");

// Updating members could've changed officers displayed in army info
SendMessageToAllArmyMembers(clients, e.ArmyGuid, "army_info_change");
}

public static void HandleEvent(ArmyRanksUpdated e, IDictionary<uint, INetworkPlayer> clients)
{
SendMessageToAllArmyMembers(clients, e.ArmyGuid, "army_rank_info_change");

// // Updating ranks could've changed officers displayed in army info
SendMessageToAllArmyMembers(clients, e.ArmyGuid, "army_info_change");
}

public static void HandleEvent(ArmyTagUpdated e, IDictionary<uint, INetworkPlayer> clients)
{
foreach (var armyMember in GetArmyMembers(clients, e.ArmyGuid))
{
var staticInfo = armyMember.CharacterEntity.StaticInfo;
staticInfo.ArmyTag = DataUtils.FormatArmyTag(e.ArmyTag);

armyMember.CharacterEntity.SetStaticInfo(staticInfo);
}
}

private static IEnumerable<INetworkPlayer> GetArmyMembers(IDictionary<uint, INetworkPlayer> clients, ulong armyGuid)
{
return clients.Values.Where(p => p.CharacterEntity.Character_BaseController.ArmyGUIDProp == armyGuid);
}

private static void SendMessageToCharacter(
IDictionary<uint, INetworkPlayer> clients, ulong characterGuid, string messageType, string initiatorName = null)
{
var player = clients.Values.FirstOrDefault(p => p.CharacterId + 0xFE == characterGuid);

if (player == null)
{
return;
}

SendMessage(player, messageType, initiatorName);
}

private static void SendMessageToAllArmyMembers(
IDictionary<uint, INetworkPlayer> clients,
ulong armyGuid,
string messageType,
string initiatorName = null)
{
var armyMembers = GetArmyMembers(clients, armyGuid);

foreach (var armyMember in armyMembers)
{
SendMessage(armyMember, messageType, initiatorName);
}
}

private static void SendMessageToAuthorizedArmyMembers(
IDictionary<uint, INetworkPlayer> clients,
RepeatedField<ulong> armyMemberGuids,
string messageType,
string initiatorName = null)
{
var armyMembers = clients.Values.Where(p => armyMemberGuids.Contains(p.CharacterId + 0xFE));

foreach (var armyMember in armyMembers)
{
SendMessage(armyMember, messageType, initiatorName);
}
}

private static void SendMessage(INetworkPlayer player, string messageType, string initiatorName = null)
{
var armyMessage = new ArmyMessage { message_type = messageType, initiator = initiatorName };

player.NetChannels[ChannelType.ReliableGss]
.SendIAero(new ReceivedWebUIMessage() { Message = JsonSerializer.Serialize(armyMessage, SerializerOptions) },
player.CharacterId);
}

private record ArmyMessage
{
public string message_type { get; init; }
public string initiator { get; init; }
public Army army { get; init; }
public Application application { get; init; }
}

private record Army
{
public ulong army_guid { get; init; }
public string name { get; init; }
}

private record Application
{
public ulong id { get; init; }
public string message { get; init; }
}
}
14 changes: 14 additions & 0 deletions UdpHosts/GameServer/GRPC/EventHandlers/CharacterEventHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using GrpcGameServerAPIClient;
using System.Collections.Generic;
using System.Linq;

namespace GameServer.GRPC.EventHandlers;

public static class CharacterEventHandler
{
public static void HandleEvent(CharacterVisualsUpdated e, IDictionary<uint, INetworkPlayer> clients)
{
clients.Values.FirstOrDefault(p => p.CharacterId + 0xFE == e.CharacterGuid)
?.CharacterEntity.LoadRemote(e.CharacterAndBattleframeVisuals);
}
}
Loading

0 comments on commit 50c4411

Please sign in to comment.