using System.Collections.Generic;
using System.Threading.Tasks;
using log4net;
using Mango.Communication.Packets.Incoming.Advertisement;
using Mango.Communication.Packets.Incoming.Catalog;
using Mango.Communication.Packets.Incoming.Handshake;
using Mango.Communication.Packets.Incoming.Inventory.Purse;
using Mango.Communication.Packets.Incoming.Messenger;
using Mango.Communication.Packets.Incoming.Navigator;
using Mango.Communication.Packets.Incoming.Room.Chat;
using Mango.Communication.Packets.Incoming.Room.Connection;
using Mango.Communication.Packets.Incoming.Room.Engine;
using Mango.Communication.Packets.Incoming.Room.Settings;
using Mango.Communication.Packets.Incoming.Tracking;
using Mango.Communication.Packets.Incoming.Users;
using Mango.Communication.Sessions;
using Mango.Communication.Packets.Incoming;
using Mango.Communication.Packets.Incoming.Inventory.Furni;
using Mango.Communication.Packets.Incoming.Inventory.Badges;
using Mango.Communication.Packets.Incoming.Inventory.Achievements;
using Mango.Communication.Packets.Incoming.Quest;
using Mango.Communication.Packets.Incoming.Room.Avatar;
using Mango.Communication.Packets.Incoming.Sound;
using System.Threading;
using System;
using System.Collections.Concurrent;
using Mango.Communication.Packets.Incoming.Room.Action;
using Mango.Communication.Packets.Incoming.Register;
using Mango.Communication.Packets.Incoming.Avatar;
using Mango.Communication.Packets.Incoming.Room.Furniture;
using Mango.Communication.Packets.Incoming.Moderator;
using Mango.Communication.Packets.Incoming.Inventory.AvatarEffects;
using Mango.Communication.Packets.Incoming.Games;
namespace Mango.Communication.Packets
{
sealed class PacketManager
{
private static readonly ILog log = LogManager.GetLogger("Mango.Communication.Packets.PacketManager");
///
/// The collection that stores all the packets to a packet id as the key.
///
private readonly Dictionary _packets;
///
/// The task factory which is used for running Asynchronous tasks, in this case we use it to execute packets.
///
private readonly TaskFactory _packetHandler;
///
/// Currently running tasks to keep track of what the current load is
///
private readonly ConcurrentDictionary _runningTasks;
///
/// Testing the Task code
///
private readonly bool IgnoreTasks = false;
///
/// The maximum time a task can run for before it is considered dead
/// (can be used for debugging any locking issues with certain areas of code)
///
private readonly int MaximumRunTimeInSec = 300; // 5 minutes
///
/// Should the handler throw errors or log and continue.
///
private readonly bool ThrowUserErrors = false;
///
/// Initializes a new instance of the PacketManager.
///
public PacketManager()
{
this._packets = new Dictionary();
this._packetHandler = new TaskFactory(TaskCreationOptions.PreferFairness, TaskContinuationOptions.None);
this._runningTasks = new ConcurrentDictionary();
}
///
/// Handles the packet provided
///
/// The session which invokes this packet.
/// The client packet received.
public void ExecutePacket(Session Session, ClientPacket Packet)
{
IPacketEvent Pak = null;
if (!_packets.TryGetValue(Packet.Id, out Pak))
{
log.Debug("Unhandled packet " + Packet.Id);
return;
}
log.Debug(" Executing packet: " + Packet.Id);
if (!IgnoreTasks)
{
DateTime Start = DateTime.Now;
var CancelSource = new CancellationTokenSource();
var Token = CancelSource.Token;
Task t = _packetHandler.StartNew(() =>
{
Pak.parse(Session, Packet);
Token.ThrowIfCancellationRequested();
}, Token);
this._runningTasks.TryAdd(t.Id, t);
try
{
if (!t.Wait(MaximumRunTimeInSec * 1000, Token))
{
CancelSource.Cancel();
}
}
catch (AggregateException ex)
{
foreach (var e in ex.Flatten().InnerExceptions)
{
if (ThrowUserErrors)
{
throw e;
}
else
{
log.Fatal("Unhandled Error: " + e.Message + " - " + e.StackTrace);
Session.Disconnect();
}
}
}
catch (OperationCanceledException)
{
Session.Disconnect();
}
finally
{
Task RemovedTask = null;
this._runningTasks.TryRemove(t.Id, out RemovedTask);
CancelSource.Dispose();
log.Debug("Event took " + (DateTime.Now - Start).Milliseconds + "ms to complete.");
}
}
else
{
Pak.parse(Session, Packet);
}
}
public void WaitForAllToComplete()
{
foreach (Task t in this._runningTasks.Values)
{
t.Wait();
}
}
public void UnregisterAll()
{
this._packets.Clear();
}
public void RegisterGames()
{
this._packets.Add(ClientPacketHeader.InitGameCenterEvent, new InitGameCenterEvent());
this._packets.Add(ClientPacketHeader.GetGameAchievementsEvent, new GetGameAchievementsEvent());
}
public void RegisterCatalog()
{
this._packets.Add(ClientPacketHeader.GetClubOffersMessageEvent, new GetClubOffersEvent());
this._packets.Add(ClientPacketHeader.GetCatalogIndexEvent, new GetCatalogIndexEvent());
this._packets.Add(ClientPacketHeader.GetCatalogPageEvent, new GetCatalogPageEvent());
this._packets.Add(ClientPacketHeader.PurchaseFromCatalogEvent, new PurchaseFromCatalogEvent());
}
public void RegisterHandshake()
{
this._packets.Add(ClientPacketHeader.GetClientVersionEvent, new GetClientVersionEvent());
this._packets.Add(ClientPacketHeader.DisconnectMessageEvent, new DisconnectEvent());
this._packets.Add(ClientPacketHeader.GenerateSecretKeyMessageEvent, new GenerateSecretKeyEvent());
this._packets.Add(ClientPacketHeader.GetSessionParametersMessageEvent, new GetSessionParametersEvent());
this._packets.Add(ClientPacketHeader.InfoRetrieveMessageEvent, new InfoRetrieveEvent());
this._packets.Add(ClientPacketHeader.InitCryptoMessageEvent, new InitCryptoEvent());
this._packets.Add(ClientPacketHeader.PongMessageEvent, new PongEvent());
this._packets.Add(ClientPacketHeader.SSOTicketMessageEvent, new SSOTicketEvent());
this._packets.Add(ClientPacketHeader.TryLoginMessageEvent, new TryLoginEvent());
this._packets.Add(ClientPacketHeader.UniqueIDMessageEvent, new UniqueIDEvent());
this._packets.Add(ClientPacketHeader.VersionCheckMessageEvent, new VersionCheckEvent());
}
public void RegisterInventoryAchievements()
{
this._packets.Add(ClientPacketHeader.GetAchievementsEvent, new GetAchievementsEvent());
}
public void RegisterInventoryAvatarEffects()
{
this._packets.Add(ClientPacketHeader.AvatarEffectActivatedEvent, new AvatarEffectActivatedEvent());
this._packets.Add(ClientPacketHeader.AvatarEffectSelectedEvent, new AvatarEffectSelectedEvent());
}
public void RegisterInventoryBadges()
{
this._packets.Add(ClientPacketHeader.GetBadgesEvent, new GetBadgesEvent());
this._packets.Add(ClientPacketHeader.SetActivatedBadgesEvent, new SetActivatedBadgesEvent());
}
public void RegisterInventoryFurni()
{
this._packets.Add(ClientPacketHeader.RequestFurniInventoryEvent, new RequestFurniInventoryEvent());
}
public void RegisterInventoryPurse()
{
this._packets.Add(ClientPacketHeader.GetCreditsInfoEvent, new GetCreditsInfoEvent());
}
public void RegisterMessenger()
{
this._packets.Add(ClientPacketHeader.AcceptBuddyMessageEvent, new AcceptBuddyEvent());
this._packets.Add(ClientPacketHeader.DeclineBuddyMessageEvent, new DeclineBuddyEvent());
this._packets.Add(ClientPacketHeader.FindNewFriendsMessageEvent, new FindNewFriendsEvent());
this._packets.Add(ClientPacketHeader.FriendListUpdateMessageEvent, new FriendListUpdateEvent());
this._packets.Add(ClientPacketHeader.GetBuddyRequestsMessageEvent, new GetBuddyRequestsEvent());
this._packets.Add(ClientPacketHeader.HabboSearchMessageEvent, new HabboSearchEvent());
this._packets.Add(ClientPacketHeader.MessengerInitMessageEvent, new MessengerInitEvent());
this._packets.Add(ClientPacketHeader.RemoveBuddyMessageEvent, new RemoveBuddyEvent());
this._packets.Add(ClientPacketHeader.RequestBuddyMessageEvent, new RequestBuddyEvent());
this._packets.Add(ClientPacketHeader.SendMsgMessageEvent, new SendMsgEvent());
this._packets.Add(ClientPacketHeader.SendRoomInviteMessageEvent, new SendRoomInviteEvent());
this._packets.Add(ClientPacketHeader.FollowFriendMessageEvent, new FollowFriendEvent());
}
public void RegisterModerator()
{
this._packets.Add(ClientPacketHeader.GetModeratorRoomInfoMessageEvent, new GetModeratorRoomInfoEvent());
this._packets.Add(ClientPacketHeader.GetModeratorUserInfoMessageEvent, new GetModeratorUserInfoEvent());
this._packets.Add(ClientPacketHeader.ModMessageMessageEvent, new ModMessageMessageEvent());
this._packets.Add(ClientPacketHeader.ModeratorActionMessageEvent, new ModeratorActionMessageEvent());
this._packets.Add(ClientPacketHeader.ModerateRoomMessageEvent, new ModerateRoomEvent());
this._packets.Add(ClientPacketHeader.OpenHelpToolMessageEvent, new OpenHelpToolEvent());
this._packets.Add(ClientPacketHeader.GetRoomChatlogMessageEvent, new GetModeratorRoomChatlogEvent());
this._packets.Add(ClientPacketHeader.GetUserChatlogMessageEvent, new GetModeratorUserChatlogEvent());
this._packets.Add(ClientPacketHeader.GetCfhChatlogMessageEvent, new GetModeratorIssueChatlogEvent());
this._packets.Add(ClientPacketHeader.GetRoomVisitsMessageEvent, new GetModeratorUserRoomVisitsEvent());
this._packets.Add(ClientPacketHeader.CallForHelpMessageEvent, new SubmitNewTicketEvent());
}
public void RegisterNavigator()
{
this._packets.Add(ClientPacketHeader.GetOfficialRoomsMessageEvent, new GetOfficialRoomsEvent());
this._packets.Add(ClientPacketHeader.GetPopularRoomTagsMessageEvent, new GetPopularRoomTagsEvent());
this._packets.Add(ClientPacketHeader.GetUserFlatCatsMessageEvent, new GetUserFlatCatsEvent());
this._packets.Add(ClientPacketHeader.LatestEventsSearchMessageEvent, new LatestEventsSearchEvent());
this._packets.Add(ClientPacketHeader.MyRoomsSearchMessageEvent, new MyRoomsSearchMessageEvent());
this._packets.Add(ClientPacketHeader.PopularRoomsSearchMessageEvent, new PopularRoomsSearchEvent());
this._packets.Add(ClientPacketHeader.RoomsWithHighestScoreSearchMessageEvent, new RoomsWithHighestScoreSearchEvent());
this._packets.Add(ClientPacketHeader.GetGuestRoomMessageEvent, new GetGuestRoomEvent());
this._packets.Add(ClientPacketHeader.CanCreateEventMessageEvent, new CanCreateEventEvent());
/*this.Packets.Add(ClientPacketHeader.CreateEventMessageEvent, new CreateEventEvent());
this.Packets.Add(ClientPacketHeader.EditEventMessageEvent, new EditEventEvent());
this.Packets.Add(ClientPacketHeader.CancelEventMessageEvent, new CancelEventEvent());*/
this._packets.Add(ClientPacketHeader.GetPublicSpaceCastLibsMessageEvent, new GetPublicSpaceCastLibsEvent());
this._packets.Add(ClientPacketHeader.RoomTextSearchMessageEvent, new RoomTextSearchEvent());
this._packets.Add(ClientPacketHeader.CanCreateRoomMessageEvent, new CanCreateRoomEvent());
this._packets.Add(ClientPacketHeader.CreateFlatMessageEvent, new CreateFlatEvent());
this._packets.Add(ClientPacketHeader.UpdateNavigatorSettingsMessageEvent, new UpdateNavigatorSettingsEvent());
this._packets.Add(ClientPacketHeader.AddFavouriteRoomMessageEvent, new AddFavouriteRoomEvent());
this._packets.Add(ClientPacketHeader.DeleteFavouriteRoomMessageEvent, new RemoveFavouriteRoomEvent());
this._packets.Add(ClientPacketHeader.MyFavouriteRoomsSearchMessageEvent, new GetFavouriteRoomsEvent());
this._packets.Add(ClientPacketHeader.PromotedRoomsEvent, new PromotedRoomsEvent());
}
public void RegisterAdvertisement()
{
this._packets.Add(ClientPacketHeader.GetRoomAdMessageEvent, new GetRoomAdEvent());
}
public void RegisterAvatar()
{
this._packets.Add(ClientPacketHeader.GetWardrobeMessageEvent, new GetWardrobeEvent());
this._packets.Add(ClientPacketHeader.SaveWardrobeOutfitMessageEvent, new SaveWardrobeOutfitEvent());
}
public void RegisterQuest()
{
this._packets.Add(ClientPacketHeader.GetQuestsMessageEvent, new GetQuestsEvent());
}
public void RegisterRegister()
{
this._packets.Add(ClientPacketHeader.UpdateFigureDataMessageEvent, new UpdateFigureDataEvent());
}
public void RegisterRoomAvatar()
{
this._packets.Add(ClientPacketHeader.LookToMessageEvent, new LookToEvent());
this._packets.Add(ClientPacketHeader.SignMessageEvent, new SignEvent());
this._packets.Add(ClientPacketHeader.WaveMessageEvent, new WaveEvent());
this._packets.Add(ClientPacketHeader.DanceMessageEvent, new DanceEvent());
this._packets.Add(ClientPacketHeader.ChangeMottoMessageEvent, new ChangeMottoEvent());
this._packets.Add(ClientPacketHeader.SitAvatarEvent, new SitEvent());
}
public void RegisterRoomChat()
{
this._packets.Add(ClientPacketHeader.ChatMessageEvent, new ChatEvent());
this._packets.Add(ClientPacketHeader.ShoutMessageEvent, new ShoutEvent());
this._packets.Add(ClientPacketHeader.StartTypingMessageEvent, new StartTypingEvent());
this._packets.Add(ClientPacketHeader.CancelTypingMessageEvent, new CancelTypingEvent());
this._packets.Add(ClientPacketHeader.WhisperMessageEvent, new WhisperEvent());
}
public void RegisterRoomAction()
{
this._packets.Add(ClientPacketHeader.LetUserInMessageEvent, new LetUserInEvent());
this._packets.Add(ClientPacketHeader.KickUserMessageEvent, new KickUserEvent());
this._packets.Add(ClientPacketHeader.BanUserMessageEvent, new BanUserEvent());
this._packets.Add(ClientPacketHeader.AssignRightsMessageEvent, new AssignRightsEvent());
this._packets.Add(ClientPacketHeader.RemoveRightsMessageEvent, new RemoveRightsEvent());
this._packets.Add(ClientPacketHeader.RemoveAllRightsMessageEvent, new RemoveAllRightsComposer());
}
public void RegisterRoom()
{
this._packets.Add(ClientPacketHeader.GoToFlatMessageEvent, new GoToFlatEvent());
this._packets.Add(ClientPacketHeader.QuitMessageEvent, new QuitEvent());
this._packets.Add(ClientPacketHeader.OpenConnectionMessageEvent, new OpenConnectionEvent());
this._packets.Add(ClientPacketHeader.OpenFlatConnectionMessageEvent, new OpenFlatConnectionEvent());
this._packets.Add(ClientPacketHeader.GetFurnitureAliasesMessageEvent, new GetFurnitureAliasesEvent());
this._packets.Add(ClientPacketHeader.GetRoomEntryDataMessageEvent, new GetRoomEntryDataEvent());
this._packets.Add(ClientPacketHeader.DeleteRoomMessageEvent, new DeleteRoomEvent());
this._packets.Add(ClientPacketHeader.GetRoomSettingsMessageEvent, new GetRoomSettingsEvent());
this._packets.Add(ClientPacketHeader.SaveRoomSettingsMessageEvent, new SaveRoomSettingsEvent());
this._packets.Add(ClientPacketHeader.MoveObjectMessageEvent, new MoveObjectEvent());
this._packets.Add(ClientPacketHeader.PlaceObjectMessageEvent, new PlaceObjectEvent());
this._packets.Add(ClientPacketHeader.MoveWallItemMessageEvent, new MoveWallItemEvent());
this._packets.Add(ClientPacketHeader.PickupObjectMessageEvent, new PickupObjectEvent());
this._packets.Add(ClientPacketHeader.MoveAvatarMessageEvent, new MoveAvatarEvent());
this._packets.Add(ClientPacketHeader.ApplyDecorationEvent, new ApplyDecorationEvent());
this._packets.Add(ClientPacketHeader.UseFurnitureMessageEvent, new UseFurnitureEvent());
this._packets.Add(ClientPacketHeader.UseWallItemMessageEvent, new UseWallItemEvent());
}
public void RegisterRoomFurniture()
{
this._packets.Add(ClientPacketHeader.DiceOffMessageEvent, new DiceOffEvent());
this._packets.Add(ClientPacketHeader.ThrowDiceMessageEvent, new ThrowDiceEvent());
}
public void RegisterSound()
{
this._packets.Add(ClientPacketHeader.GetSoundSettingsEvent, new GetSoundSettingsEvent());
this._packets.Add(ClientPacketHeader.SetSoundSettingsEvent, new SetSoundSettingsEvent());
}
public void RegisterTracking()
{
this._packets.Add(ClientPacketHeader.EventLogMessageEvent, new EventLogEvent());
}
public void RegisterUsers()
{
this._packets.Add(ClientPacketHeader.GetHabboGroupBadgesMessageEvent, new GetHabboGroupBadgesEvent());
this._packets.Add(ClientPacketHeader.GetMOTDMessageEvent, new GetMOTDEvent());
this._packets.Add(ClientPacketHeader.GetUserNotificationsMessageEvent, new GetUserNotificationsEvent());
this._packets.Add(ClientPacketHeader.GetSelectedBadgesMessageEvent, new GetSelectedBadgesEvent());
this._packets.Add(ClientPacketHeader.RespectUserMessageEvent, new RespectUserEvent());
this._packets.Add(ClientPacketHeader.GetProfileInformationEvent, new GetProfileInformationEvent());
}
}
}