Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Channel Communication #627

Merged
2 changes: 1 addition & 1 deletion Arrowgene.Ddon.GameServer/Characters/CharacterManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public Character SelectCharacter(uint characterId)
return null;
}

character.Server = _Server.AssetRepository.ServerList.Where(server => server.Id == _Server.Id).Single();
character.Server = _Server.AssetRepository.ServerList.Where(server => server.Id == _Server.Id).Single().ToCDataGameServerListInfo();
character.Equipment = character.Storage.GetCharacterEquipment();

character.ExtendedParams = _Server.Database.SelectOrbGainExtendParam(character.CommonId);
Expand Down
92 changes: 71 additions & 21 deletions Arrowgene.Ddon.GameServer/Characters/ClanManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Arrowgene.Ddon.Shared.Entity.Structure;
using Arrowgene.Ddon.Shared.Model;
using Arrowgene.Ddon.Shared.Model.Clan;
using Arrowgene.Ddon.Shared.Network;
using Arrowgene.Logging;
using System;
using System.Collections.Generic;
Expand Down Expand Up @@ -53,6 +54,17 @@ public class ClanManager

private static readonly TimeSpan CLAN_CACHE_TIME = TimeSpan.FromHours(1);

/// <summary>
/// Packets that get sent to all channels, even if there isn't a clan member there to recieve them.
/// These have side-effects on the internal tracking of clans.
/// </summary>
public static readonly HashSet<PacketId> INTERNAL_IMPORTANT_PACKETS = new HashSet<PacketId>()
{
PacketId.S2C_CLAN_CLAN_UPDATE_NTC,
PacketId.S2C_CLAN_CLAN_LEAVE_MEMBER_NTC,
PacketId.S2C_CLAN_CLAN_JOIN_MEMBER_NTC
};

public static readonly uint[] TOTAL_CP_FOR_ADV = new uint[] {
/********/ 0,
/* Lv 1 */ 500,
Expand Down Expand Up @@ -122,6 +134,32 @@ public CDataClanParam GetClan(uint id)
}
}

public void ResyncClan(uint id)
{
lock (ClanParams)
{
if (!ClanParams.ContainsKey(id))
{
var clan = Server.Database.SelectClan(id);

if (clan.ClanServerParam.ID == 0)
{
// Failed to fetch the clan, because it doesn't exist.
// Throw an exception?
throw new ResponseErrorException(ErrorCode.ERROR_CODE_CLAN_NOT_EXIST);
}

clan.ClanServerParam.NextClanPoint = TOTAL_CP_FOR_ADV[clan.ClanServerParam.Lv];
AddClan(clan);
}
else
{
ClanParams[id].Obj = Server.Database.SelectClan(id);
ClanParams[id].Sync();
}
}
}

public CDataClanParam CreateClan(GameClient client, CDataClanUserParam createParam)
{
var serverParam = new CDataClanServerParam()
Expand Down Expand Up @@ -169,6 +207,7 @@ public CDataClanParam CreateClan(GameClient client, CDataClanUserParam createPar
{
otherClient.Send(joinNtc);
}
Server.RpcManager.AnnouncePlayerJoin(client.Character); // Resend this join notice to update the clan info.

return newClan;
}
Expand All @@ -183,13 +222,7 @@ public void UpdateClan(GameClient client, CDataClanUserParam updateParam)
clan.ClanUserParam = updateParam;
Server.Database.UpdateClan(clan);

foreach (var otherClient in Server.ClientLookup.GetAll())
{
if (otherClient.Character != null && otherClient.Character.ClanId == client.Character.ClanId)
{
otherClient.Send(new S2CClanClanUpdateNtc());
}
}
SendToClan(client.Character.ClanId, new S2CClanClanUpdateNtc());
}
}

Expand Down Expand Up @@ -254,7 +287,7 @@ public void LeaveClan(uint characterId, uint clanId)
}

var memberList = MemberList(clanId);
var character = memberList.Where(x => x.CharacterListElement.CommunityCharacterBaseInfo.CharacterId == characterId).FirstOrDefault();
var memberInfo = memberList.Where(x => x.CharacterListElement.CommunityCharacterBaseInfo.CharacterId == characterId).FirstOrDefault();

Server.Database.ExecuteInTransaction(conn =>
{
Expand All @@ -270,24 +303,29 @@ public void LeaveClan(uint characterId, uint clanId)
}
});

Character characterLookup = Server.ClientLookup.GetClientByCharacterId(characterId)?.Character;
if (character != null)
{
character.CharacterListElement.CommunityCharacterBaseInfo.ClanName = string.Empty;
characterLookup.ClanId = 0;
characterLookup.ClanName.Name = string.Empty;
characterLookup.ClanName.ShortName = string.Empty;
}

var ntc = new S2CClanClanLeaveMemberNtc()
{
ClanId = 0,
CharacterListElement = character.CharacterListElement
CharacterListElement = memberInfo.CharacterListElement
};
foreach (var client in Server.ClientLookup.GetAll())
{
client.Send(ntc);
}
Server.RpcManager.AnnounceClanPacket(clanId, ntc);

if (memberInfo != null)
{
memberInfo.CharacterListElement.CommunityCharacterBaseInfo.ClanName = string.Empty;
}

Character characterLookup = Server.ClientLookup.GetClientByCharacterId(characterId)?.Character;
if (characterLookup != null)
{
characterLookup.ClanId = 0;
characterLookup.ClanName.Name = string.Empty;
characterLookup.ClanName.ShortName = string.Empty;
}
}

public void SetMemberRank(uint characterId, uint clanId, uint rank, uint permission)
Expand All @@ -306,13 +344,15 @@ public void SetMemberRank(uint characterId, uint clanId, uint rank, uint permiss
Server.Database.UpdateClanMember(memberInfo, clanId, conn);
});

SendToClan(clanId, new S2CClanClanSetMemberRankNtc()
var rankNtc = new S2CClanClanSetMemberRankNtc()
{
ClanId = clanId,
CharacterId = characterId,
Rank = rank,
Permission = permission
});
};

SendToClan(clanId, rankNtc);
}

public void NegotiateMaster(uint characterId, uint clanId)
Expand Down Expand Up @@ -410,7 +450,16 @@ public List<CDataClanMemberInfo> MemberList(uint clanId)
}
else
{
member.CharacterListElement.OnlineStatus = OnlineStatus.Offline;
var channelId = Server.RpcManager.FindPlayerById(memberInfo.CharacterId);
if (channelId > 0)
{
member.CharacterListElement.OnlineStatus = OnlineStatus.Online;
member.CharacterListElement.ServerId = channelId;
}
else
{
member.CharacterListElement.OnlineStatus = OnlineStatus.Offline;
}
}
}
return memberList;
Expand Down Expand Up @@ -441,6 +490,7 @@ public void SendToClan<T>(uint clanId, T packet)
client.Send(packet);
}
}
Server.RpcManager.AnnounceClanPacket(clanId, packet);
}

// Will likely need this later for clan searching.
Expand Down
79 changes: 65 additions & 14 deletions Arrowgene.Ddon.GameServer/Chat/ChatManager.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
using System.Collections.Generic;
using System.Linq;
using Arrowgene.Ddon.GameServer.Party;
using Arrowgene.Ddon.Server;
using Arrowgene.Ddon.Shared.Entity.PacketStructure;
using Arrowgene.Ddon.Shared.Entity.Structure;
using Arrowgene.Ddon.Shared.Model;
using Arrowgene.Logging;
using System.Collections.Generic;
using System.Linq;

namespace Arrowgene.Ddon.GameServer.Chat
{
Expand All @@ -14,13 +14,11 @@ public class ChatManager
private static readonly ServerLogger Logger = LogProvider.Logger<ServerLogger>(typeof(ChatManager));

private readonly List<IChatHandler> _handler;
private readonly GameRouter _router;
private readonly DdonGameServer _server;

public ChatManager(DdonGameServer server, GameRouter router)
public ChatManager(DdonGameServer server)
{
_server = server;
_router = router;
_handler = new List<IChatHandler>();
}

Expand Down Expand Up @@ -53,7 +51,7 @@ public void SendMessage(string message, string firstName, string lastName, Lobby
response.Recipients.Add(client);
}

_router.Send(response);
Send(response);
}

public void SendMessage(string message, string firstName, string lastName, LobbyChatMsgType type,
Expand All @@ -73,19 +71,43 @@ public void SendMessage(string message, string firstName, string lastName, Lobby
PhrasesIndex = 0
};
response.Recipients.AddRange(recipients);
_router.Send(response);
Send(response);
}

// TODO: add support for sending tell messages across worlds - requires some form of access to available worlds and their associated clients
public void SendTellMessage(uint handleId, CDataCommunityCharacterBaseInfo senderCharacterInfo, CDataCommunityCharacterBaseInfo receiverCharacterInfo, C2SChatSendTellMsgReq request, GameClient sender, GameClient receiver)
public void SendTellMessage(GameClient sender, GameClient receiver, C2SChatSendTellMsgReq request)
{
ChatResponse senderChatResponse = GetTellChatResponse(handleId, receiverCharacterInfo, request);
var senderCharacterInfo = sender.Character.GetCommunityCharacterBaseInfo();
var receiverCharacterInfo = receiver.Character.GetCommunityCharacterBaseInfo();
ChatResponse senderChatResponse = GetTellChatResponse(senderCharacterInfo.CharacterId, receiverCharacterInfo, request);
senderChatResponse.Recipients.Add(sender);
ChatResponse receiverChatResponse = GetTellChatResponse(handleId, senderCharacterInfo, request);
ChatResponse receiverChatResponse = GetTellChatResponse(senderCharacterInfo.CharacterId, senderCharacterInfo, request);
receiverChatResponse.Recipients.Add(receiver);

_router.Send(senderChatResponse);
_router.Send(receiverChatResponse);
Send(senderChatResponse);
Send(receiverChatResponse);
}

public void SendTellMessageForeign(GameClient client, C2SChatSendTellMsgReq request)
{
_server.RpcManager.AnnounceTellChat(client, request);

ChatResponse senderChatResponse = new ChatResponse
{
HandleId = request.CharacterInfo.CharacterId,
Deliver = false,
FirstName = request.CharacterInfo.CharacterName.FirstName,
LastName = request.CharacterInfo.CharacterName.LastName,
ClanName = request.CharacterInfo.ClanName,
CharacterId = request.CharacterInfo.CharacterId,
Type = LobbyChatMsgType.Tell,
Message = request.Message,
MessageFlavor = request.MessageFlavor,
PhrasesCategory = request.PhrasesCategory,
PhrasesIndex = request.PhrasesIndex
};

senderChatResponse.Recipients.Add(client);
Send(senderChatResponse);
}

public void Handle(GameClient client, ChatMessage message)
Expand Down Expand Up @@ -154,13 +176,15 @@ private void Deliver(GameClient client, ChatResponse response)
&& client.Character != null
&& x.Character.ClanId == client.Character.ClanId)
);

_server.RpcManager.AnnounceClanChat(client, response);
break;
default:
response.Recipients.Add(client);
break;
}

_router.Send(response);
Send(response);
}

public static S2CLobbyChatMsgNotice GetTellMsgNtc(uint handleId, CDataCommunityCharacterBaseInfo characterInfo, C2SChatSendTellMsgReq request)
Expand Down Expand Up @@ -194,5 +218,32 @@ public static ChatResponse GetTellChatResponse(uint handleId, CDataCommunityChar
PhrasesIndex = request.PhrasesIndex
};
}

public void Send(ChatResponse response)
{
S2CLobbyChatMsgNotice notice = new S2CLobbyChatMsgNotice
{
HandleId = response.HandleId,
Type = response.Type,
MessageFlavor = response.MessageFlavor,
PhrasesCategory = response.PhrasesCategory,
PhrasesIndex = response.PhrasesIndex,
Message = response.Message,
CharacterBaseInfo =
{
CharacterId = response.CharacterId,
CharacterName =
{
FirstName = response.FirstName,
LastName = response.LastName
},
ClanName = response.ClanName
}
};
foreach (GameClient client in response.Recipients.Distinct())
{
client.Send(notice);
}
}
}
}
6 changes: 3 additions & 3 deletions Arrowgene.Ddon.GameServer/DdonGameServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,9 @@ public DdonGameServer(GameServerSetting setting, IDatabase database, AssetReposi
: base(ServerType.Game, setting.ServerSetting, database, assetRepository)
{
Setting = new GameServerSetting(setting);
Router = new GameRouter();
ClientLookup = new GameClientLookup();
ChatLogHandler = new ChatLogHandler();
ChatManager = new ChatManager(this, Router);
ChatManager = new ChatManager(this);
ItemManager = new ItemManager(this);
CraftManager = new CraftManager(this);
PartyManager = new PartyManager(this);
Expand All @@ -78,6 +77,7 @@ public DdonGameServer(GameServerSetting setting, IDatabase database, AssetReposi
BoardManager = new BoardManager(this);
TimerManager = new TimerManager(this);
ClanManager = new ClanManager(this);
RpcManager = new RpcManager(this);

// Orb Management is slightly complex and requires updating fields across multiple systems
OrbUnlockManager = new OrbUnlockManager(database, WalletManager, JobManager, CharacterManager);
Expand Down Expand Up @@ -105,14 +105,14 @@ public DdonGameServer(GameServerSetting setting, IDatabase database, AssetReposi
public RewardManager RewardManager { get; }
public StampManager StampManager { get; }
public HubManager HubManager { get; }
public GameRouter Router { get; }
public GpCourseManager GpCourseManager { get; }
public WeatherManager WeatherManager { get; }
public PartyQuestContentManager PartyQuestContentManager { get; }
public BonusDungeonManager BonusDungeonManager { get; }
public BoardManager BoardManager { get; }
public TimerManager TimerManager { get; }
public ClanManager ClanManager { get; }
public RpcManager RpcManager { get; }

public ChatLogHandler ChatLogHandler { get; }

Expand Down
Loading
Loading