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

Persistent Client Preferences and Friends of Friends Packets #48

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -337,4 +337,7 @@ ASALocalRun/
.localhistory/

# BeatPulse healthcheck temp database
healthchecksdb
healthchecksdb

src/PFire.Console/Logs/
src/PFire.Console/*.sqlite*
31 changes: 31 additions & 0 deletions src/PFire.Core/Models/ChatroomModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PFire.Core.Models
{
internal class ChatroomModel
{
public byte[] Id { get; set; } = new byte[21];
public string Name { get; set; } = "";
public int Visibility { get; set; } = 1;
public int DefaultPerms { get; set; } = 2;
public List<int> Users { get; set; } = new List<int>();
public List<int> PowerUsers { get; set; } = new List<int>();
public List<int> Moderators { get; set; } = new List<int>();
public List<int> Administrators { get; set; } = new List<int>();
public List<int> SilencedUsers { get; set; } = new List<int>();
public byte ShowJoinLeaveMessages { get; set; } = 1;
public byte SavedRoom { get; set; } = 0;
public byte Silenced { get; set; } = 0;
public string MOTD { get; set; } = "";
public string Password { get; set; } = "";
public int GameLobbyHost { get; set; } = 0;
public int GameLobbyID { get; set; } = 0;
public int GameLobbyIP { get; set; } = 0;
public int GameLobbyPort { get; set; } = 0;
public List<int> GameLobbyPlayers { get; set; } = new List<int>();
}
}
24 changes: 24 additions & 0 deletions src/PFire.Core/Models/Screenshot.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System;

namespace PFire.Core.Entities
{
public class Screenshot
{
public int Id { get; set; } = 0;
public bool AdultContent { get; set; } = false;
public string FileName { get; set; }
public string Description { get; set; } = "";
public DateTime Uploaded { get; set; }
public DateTime Created { get; set; }
public string GameShortName { get; set; } = "";
public string GameLongName { get; set; } = "";
public string Nickname { get; set; } = "";
public int ViewCount { get; set; } = 0;
public int ServerIp { get; set; } = 0;
public int ServerPort { get; set; } = 0;
public int GameId { get; set; } = 0;
public int FileSize { get; set; } = 0;
public int CreatedUnixTimestamp { get; set; }
public int LockedState { get; set; } = 0;
}
}
21 changes: 20 additions & 1 deletion src/PFire.Core/Models/User.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
namespace PFire.Core.Models
using System.Collections.Generic;

namespace PFire.Core.Models
{
public class UserModel
{
Expand All @@ -7,5 +9,22 @@ public class UserModel
public string Password { get; set; }
public string Nickname { get; set; }
public GameModel Game { get; set; } = new GameModel();
public bool ShowGameStatusToFriends { get; set; }
public bool ShowGameServerData { get; set; }
public bool ShowGameDataOnProfile { get; set; }
public bool ShowTimeStampInChat { get; set; }
public bool ShowVoiceChatServer { get; set; }
public bool ShowTyping { get; set; }
public bool ShowFriendsOfFriends { get; set; }
public bool PlaySoundOnNewMessages { get; set; }
public bool PlaySoundsOnNewMessagesInGame { get; set; }
public bool PlaySoundsOnLogOn { get; set; }
public bool ShowOfflineFriends { get; set; }
public bool ShowNicknames { get; set; }
public bool ShowTooltipOnLogOn { get; set; }
public bool ShowTooltipOnDownload { get; set; }
public bool PlaySoundInChatrooms { get; set; }
public bool PlaySoundOnVoicecalls { get; set; }
public bool PlaySoundOnScreenshots { get; set; }
}
}
26 changes: 26 additions & 0 deletions src/PFire.Core/PFireServer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using PFire.Core.Models;
using PFire.Core.Protocol.Messages;
Expand Down Expand Up @@ -97,7 +98,32 @@ private void AddSession(IXFireClient session)

public void RemoveSession(IXFireClient session)
{
RemoveGamingSession(session);
_clientManager.RemoveSession(session);
}

public async void RemoveGamingSession(IXFireClient context)
{
context.User.Game.Id = 0;
context.User.Game.Ip = 0;
context.User.Game.Port = 0;

await context.Server.SendGameInfoToFriends(context);
}
internal async Task SendGameInfoToFriends(IXFireClient context)
{
var sessionsToSendTo = (await context.Server.Database.QueryFriends(context.User))
.Union(await context.Server.Database.QueryFriendsOfFriends(context.User))
.Distinct()
.Select(friendId => context.Server.GetSession(friendId))
.Where(session => session != null && context.User.Id != session.User.Id)
.ToList();

foreach (var session in sessionsToSendTo)
{
await session.SendAndProcessMessage(new FriendsGamesInfo([context.User]));
}

}
}
}
39 changes: 28 additions & 11 deletions src/PFire.Core/Protocol/MessageSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,23 @@ public static IMessage Deserialize(BinaryReader reader, IMessage messageBase)

for (var i = 0; i < attributeCount; i++)
{
var attributeName = GetAttributeName(reader, messageType);
var attributeNameAsBytes = GetAttributeNameAsBytes(reader, messageType);

var attributeType = reader.ReadByte();

var value = XFireAttributeFactory.Instance.GetAttribute(attributeType).ReadValue(reader);

var field = fieldInfo.Where(a => a.GetCustomAttribute<XMessageField>() != null)
.FirstOrDefault(a => a.GetCustomAttribute<XMessageField>()?.Name == attributeName);
var field = fieldInfo
.Where(a => a.GetCustomAttribute<XMessageField>() != null)
.FirstOrDefault(a => a.GetCustomAttribute<XMessageField>().NameAsBytes.SequenceEqual(attributeNameAsBytes));

if (field != null)
{
field.SetValue(messageBase, value);
}
else
{
Debug.WriteLine($"WARN: No attribute defined for {attributeName} on class {messageType.Name}");
Debug.WriteLine($"WARN: No attribute defined for {attributeNameAsBytes} on class {messageType.Name}");
}
}

Expand All @@ -59,15 +60,31 @@ public static IMessage Deserialize(BinaryReader reader, IMessage messageBase)
return messageBase;
}

private static string GetAttributeName(BinaryReader reader, Type messageType)
private static byte[] GetAttributeNameAsBytes(BinaryReader reader, Type messageType)
{
// TODO: Be brave enough to find an elegant fix for this
// XFire decides not to follow its own rules. Message type 32 does not have a prefix byte for the length of the attribute name
// and breaks this code. Assume first byte after the attribute count as the attribute name
var count = (messageType == typeof(StatusChange) || messageType == typeof(GameServerFetchAll)) ? 1 : reader.ReadByte();
// These messages contain a single field represented by a byte value instead of
// the usual first byte representing the attribute name length.
var messagesWithoutAttributeNames = new HashSet<Type>
{
typeof(StatusChange),
typeof(GameServerFetchAll),
typeof(GroupCreate),
typeof(GroupMemberAdd),
typeof(GroupMemberRemove),
typeof(GroupRemove),
typeof(GroupRename),
typeof(GameClientData),
typeof(UserRequestAdvancedInfo)
};


if (messagesWithoutAttributeNames.Contains(messageType))
{
return [reader.ReadByte()];
}

var readBytes = reader.ReadBytes(count);
return Encoding.UTF8.GetString(readBytes);
var length = reader.ReadByte();
return reader.ReadBytes(length);
}

public static byte[] Serialize(IMessage message)
Expand Down
Loading
Loading