...
 
Commits (7)
......@@ -26,13 +26,9 @@ namespace Tangine.Modules
Id = id;
IsOutgoing = isOutgoing;
}
public DataCaptureAttribute(Type dataType, string pattern)
public DataCaptureAttribute(Predicate<HPacket> matcher)
{
}
public DataCaptureAttribute(Predicate<HPacket> dataMatcher)
{
DataMatcher = dataMatcher;
DataMatcher = matcher;
}
}
}
\ No newline at end of file
......@@ -5,13 +5,12 @@ using System.Collections.Generic;
using Tanji.Network;
using Tanji.Services;
using Tanji.Windows.Logger;
using Tanji.Services.Modules;
using Tanji.Services.Connection;
using Tangine.Habbo;
using Tangine.Modules;
using Tangine.Network;
using Tanji.Services.Modules;
using Tanji.Testing;
namespace Tanji
{
......@@ -55,7 +54,6 @@ namespace Tanji
{
case nameof(ModulesViewModel): rank = 0; break;
case nameof(ConnectionViewModel): rank = 1; break;
case nameof(OhShitItsDatEggGrabberBoi): rank = 2; break;
case nameof(LoggerViewModel): rank = 10; break;
......
......@@ -6,6 +6,7 @@ using System.Collections.Generic;
using Tanji.Helpers;
using Tangine.Modules;
using Tangine.Network;
namespace Tanji.Services.Modules.Models
{
......@@ -23,7 +24,7 @@ namespace Tanji.Services.Modules.Models
public Form UserInterface { get; set; }
private IModule _instance = null;
private IModule _instance;
public IModule Instance
{
get { return _instance; }
......@@ -38,5 +39,10 @@ namespace Tanji.Services.Modules.Models
{
Authors = new List<AuthorAttribute>();
}
public void HandleData(DataInterceptedEventArgs e)
{
Instance?.HandleData(e);
}
}
}
\ No newline at end of file
......@@ -60,7 +60,10 @@ namespace Tanji.Services.Modules
if (_installModuleDialog.ShowDialog() != DialogResult.Cancel)
{
ModuleModel module = InstallModule(_installModuleDialog.FileName);
InitializeModule(module); // TODO: Remove after debugging.
if (module != null)
{
InitializeModule(module); // TODO: Remove after debugging.
}
}
}
......@@ -116,7 +119,7 @@ namespace Tanji.Services.Modules
try
{
// Copy the required dependencies, since utilizing 'ExportedTypes' will attempt to load them when enumerated.
CopyDependencies(path, module.Assembly); // TODO: Load them when they are asked for in 'Assembly_Resolve'.
CopyDependencies(path, module.Assembly);
AppDomain.CurrentDomain.AssemblyResolve += Assembly_Resolve;
foreach (Type type in module.Assembly.ExportedTypes)
{
......@@ -124,6 +127,8 @@ namespace Tanji.Services.Modules
module.Type = type;
var moduleAtt = type.GetCustomAttribute<ModuleAttribute>();
if (moduleAtt == null) break; // Module attribute is required.
module.Description = moduleAtt.Description;
module.Name = moduleAtt.Name;
......@@ -227,8 +232,6 @@ namespace Tanji.Services.Modules
}
return copiedFilePath;
}
// TODO: Resolve all module dependencies through the 'Assembly_Resolve' method.
private void CopyDependencies(string filePath, Assembly fileAsm)
{
AssemblyName[] references = fileAsm.GetReferencedAssemblies();
......@@ -261,19 +264,6 @@ namespace Tanji.Services.Modules
}
}
}
private FileSystemInfo GetDependencyFile(DirectoryInfo directory, string dependencyName)
{
FileSystemInfo[] libraries = directory.GetFileSystemInfos("*.dll");
foreach (FileSystemInfo library in libraries)
{
string libraryName = AssemblyName.GetAssemblyName(library.FullName).FullName;
if (libraryName == dependencyName)
{
return library;
}
}
return null;
}
private void ModuleForm_Closed(object sender, FormClosedEventArgs e)
{
......@@ -285,25 +275,39 @@ namespace Tanji.Services.Modules
DisposeModule(module);
}
private void Module_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case nameof(ModuleModel.Instance):
{
IsReceiving = (GetRunningModules().Count() > 0);
break;
}
}
}
private Assembly Assembly_Resolve(object sender, ResolveEventArgs e)
{
FileSystemInfo dependency = GetDependencyFile(DependenciesDirectory, e.Name);
if (dependency != null)
FileSystemInfo dependencyFile = GetDependencyFile(DependenciesDirectory, e.Name);
if (dependencyFile != null)
{
return Assembly.Load(File.ReadAllBytes(dependency.FullName));
return Assembly.Load(File.ReadAllBytes(dependencyFile.FullName));
}
return null;
}
private void Module_PropertyChanged(object sender, PropertyChangedEventArgs e)
private FileSystemInfo GetDependencyFile(DirectoryInfo directory, string dependencyName)
{
switch (e.PropertyName)
FileSystemInfo[] libraries = directory.GetFileSystemInfos("*.dll");
foreach (FileSystemInfo library in libraries)
{
case nameof(ModuleModel.Instance):
string libraryName = AssemblyName.GetAssemblyName(library.FullName).FullName;
if (libraryName == dependencyName)
{
IsReceiving = (GetRunningModules().Count() > 0);
break;
return library;
}
}
return null;
}
#region IHaltable Implementation
......@@ -315,7 +319,22 @@ namespace Tanji.Services.Modules
#region IReceiver Implementation
public bool IsReceiving { get; private set; }
public void HandleData(DataInterceptedEventArgs e)
{ }
{
foreach (ModuleModel module in Modules.ToArray())
{
if (module.Instance == null) continue;
try
{
// Continue checking for null, the Instance property could have been changed.
module.Instance?.HandleData(e);
}
catch
{
// TODO: Display informative error to user with last read values/packet.
e.Restore();
}
}
}
#endregion
}
}
\ No newline at end of file
......@@ -134,15 +134,6 @@
</Compile>
<Compile Include="Services\Toolbox\ToolboxViewModel.cs" />
<Compile Include="Services\IMaster.cs" />
<Compile Include="Testing\OhShitItsDatEggGrabberBoi.cs" />
<Compile Include="Testing\Stuff\HEntity.cs" />
<Compile Include="Testing\Stuff\HEntityAction.cs" />
<Compile Include="Testing\Stuff\HFurniture.cs" />
<Compile Include="Testing\Stuff\HItem.cs" />
<Compile Include="Testing\Stuff\HMap.cs" />
<Compile Include="Testing\Stuff\HPoint.cs" />
<Compile Include="Testing\Stuff\HStuffData.cs" />
<Compile Include="Testing\Stuff\IHEntity.cs" />
<Compile Include="Windows\Logger\LoggerView.xaml.cs">
<DependentUpon>LoggerView.xaml</DependentUpon>
</Compile>
......
using Tanji.Helpers;
using Tanji.Services;
using Tangine.Network;
namespace Tanji.Testing
{
public class OhShitItsDatEggGrabberBoi : ObservableObject, IReceiver
{
public bool IsReceiving { get; } = true;
public void HandleData(DataInterceptedEventArgs e)
{
if (!e.IsOutgoing)
{
switch (e.Packet.Id)
{
default: break;
}
}
}
}
}
\ No newline at end of file
using System.Globalization;
using System.Collections.Generic;
using Tangine.Habbo;
using Tangine.Network.Protocol;
namespace Sulakore.Habbo
{
/// <summary>
/// Represents an in-game object that provides special information that makes it unique in a room.
/// </summary>
public class HEntity : IHEntity
{
/// <summary>
/// Gets or sets the id of the <see cref="HEntity"/>.
/// </summary>
public int Id { get; set; }
/// <summary>
/// Gets or sets the room index value of the <see cref="HEntity"/>.
/// </summary>
public int Index { get; set; }
/// <summary>
/// Gets or sets the name of the <see cref="HEntity"/>.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Gets or sets the motto of the <see cref="HEntity"/>.
/// </summary>
public string Motto { get; set; }
/// <summary>
/// Gets or sets the figure id of the <see cref="HEntity"/>.
/// </summary>
public string FigureId { get; set; }
/// <summary>
/// Gets or sets the favorite group badge of the <see cref="HEntity"/>.
/// </summary>
public string FavoriteGroup { get; set; }
/// <summary>
/// Gets or sets the <see cref="HPoint"/> of the <see cref="HEntity"/>.
/// </summary>
public HPoint Tile { get; set; }
/// <summary>
/// Gets or sets the gender of the <see cref="HEntity"/>.
/// </summary>
public HGender Gender { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="HEntity"/> class with the specified information,
/// </summary>
/// <param name="id">The id of the <see cref="HEntity"/>.</param>
/// <param name="index">The room index value of the <see cref="HEntity"/>.</param>
/// <param name="name">The name of the <see cref="HEntity"/>.</param>
/// <param name="tile">The <see cref="HPoint"/> of the <see cref="HEntity"/>.</param>
/// <param name="motto">The motto of the <see cref="HEntity"/>.</param>
/// <param name="gender">The <see cref="HGender"/> of the <see cref="HEntity"/>.</param>
/// <param name="figureId">The figure id of the <see cref="HEntity"/>.</param>
/// <param name="favoriteGroup">The favorite group badge of the <see cref="HEntity"/>.</param>
public HEntity(int id, int index, string name, HPoint tile,
string motto, HGender gender, string figureId, string favoriteGroup)
{
Id = id;
Index = index;
Name = name;
Tile = tile;
Motto = motto;
Gender = gender;
FigureId = figureId;
FavoriteGroup = favoriteGroup;
}
/// <summary>
/// Returns a <see cref="IReadOnlyList{T}"/> of type <see cref="HEntity"/> found in the <see cref="HMessage"/>.
/// </summary>
/// <param name="packet">The <see cref="HMessage"/> that contains the <see cref="HEntity"/> data to parse.</param>
/// <returns></returns>
public static IReadOnlyList<HEntity> Parse(HPacket packet)
{
int entityCount = packet.ReadInt32();
var entityList = new List<HEntity>(entityCount);
for (int i = 0; i < entityList.Capacity; i++)
{
int id = packet.ReadInt32();
string name = packet.ReadUTF8();
string motto = packet.ReadUTF8();
string figureId = packet.ReadUTF8();
int index = packet.ReadInt32();
int x = packet.ReadInt32();
int y = packet.ReadInt32();
var z = double.Parse(
packet.ReadUTF8(), CultureInfo.InvariantCulture);
packet.ReadInt32();
int type = packet.ReadInt32();
HGender gender = HGender.Unisex;
string favoriteGroup = string.Empty;
#region Switch: type
switch (type)
{
case 1:
{
gender = (HGender)packet.ReadUTF8().ToUpper()[0];
packet.ReadInt32();
packet.ReadInt32();
favoriteGroup = packet.ReadUTF8();
packet.ReadUTF8();
packet.ReadInt32();
packet.ReadBoolean();
break;
}
case 2:
{
packet.ReadInt32();
packet.ReadInt32();
packet.ReadUTF8();
packet.ReadInt32();
packet.ReadBoolean();
packet.ReadBoolean();
packet.ReadBoolean();
packet.ReadBoolean();
packet.ReadBoolean();
packet.ReadBoolean();
packet.ReadInt32();
packet.ReadUTF8();
break;
}
case 4:
{
packet.ReadUTF8();
packet.ReadInt32();
packet.ReadUTF8();
for (int j = packet.ReadInt32(); j > 0; j--)
packet.ReadUInt16();
break;
}
}
#endregion
var entity = new HEntity(id, index, name,
new HPoint(x, y, z), motto, gender, figureId, favoriteGroup);
entityList.Add(entity);
}
return entityList;
}
/// <summary>
/// Converts the <see cref="HEntity"/> to a human-readable string.
/// </summary>
/// <returns></returns>
public override string ToString()
{
return $"{nameof(Id)}: {Id}, {nameof(Index)}: {Index}, {nameof(Name)}: {Name}, " +
$"{nameof(Tile)}: {Tile}, {nameof(Motto)}: {Motto}, {nameof(Gender)}: {Gender}, " +
$"{nameof(FigureId)}: {FigureId}, {nameof(FavoriteGroup)}: {FavoriteGroup}";
}
}
}
\ No newline at end of file
using System;
using System.Globalization;
using System.Collections.Generic;
using Tangine.Habbo;
using Tangine.Network.Protocol;
namespace Sulakore.Habbo
{
/// <summary>
/// Represents an <see cref="IHEntity"/> performing actions.
/// </summary>
public class HEntityAction : IHEntity
{
/// <summary>
/// Gets or sets the room index value of the <see cref="IHEntity"/>.
/// </summary>
public int Index { get; set; }
/// <summary>
/// Gets or sets a value that determines whether the <see cref="IHEntity"/> has privileges.
/// </summary>
public bool IsEmpowered { get; set; }
/// <summary>
/// Gets or sets the <see cref="HPoint"/> of where the <see cref="IHEntity"/> is currently on.
/// </summary>
public HPoint Tile { get; set; }
/// <summary>
/// Gets or sets the <see cref="HPoint"/> of where the <see cref="IHEntity"/> will move to next.
/// </summary>
public HPoint MovingTo { get; set; }
/// <summary>
/// Gets or sets the <see cref="HSign"/> that the <see cref="IHEntity"/> has raised.
/// </summary>
public HSign Sign { get; set; }
/// <summary>
/// Gets or sets the current <see cref="HStance"/> of the <see cref="IHEntity"/>.
/// </summary>
public HStance Stance { get; set; }
/// <summary>
/// Gets or sets the <see cref="HAction"/> that the <see cref="IHEntity"/> has recently done.
/// </summary>
public HAction LastAction { get; set; }
/// <summary>
/// Gets or sets the head <see cref="HDirection"/> of the <see cref="IHEntity"/>.
/// </summary>
public HDirection HeadDirection { get; set; }
/// <summary>
/// Gets or sets the body <see cref="HDirection"/> of the <see cref="IHEntity"/>.
/// </summary>
public HDirection BodyDirection { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="HEntityAction"/> class with the specified information.
/// </summary>
/// <param name="isEmpowered">The value that determines whether the <see cref="IHEntity"/> has privileges.</param>
/// <param name="index">The room index value of the <see cref="IHEntity"/>.</param>
/// <param name="tile">The <see cref="HPoint"/> of where the <see cref="IHEntity"/> is currently on.</param>
/// <param name="movingTo">The <see cref="HPoint"/> of where the <see cref="IHEntity"/> will move to next.</param>
/// <param name="sign">The <see cref="HSign"/> that the <see cref="IHEntity"/> has raised.</param>
/// <param name="stance">The current <see cref="HStance"/> of the <see cref="IHEntity"/>.</param>
/// <param name="headDirection">The <see cref="HDirection"/> of the <see cref="IHEntity"/>'s head.</param>
/// <param name="bodyDirection">The <see cref="HDirection"/> of the <see cref="IHEntity"/>'s body.</param>
/// <param name="lastAction">The <see cref="HAction"/> that the <see cref="IHEntity"/> has recently done.</param>
public HEntityAction(bool isEmpowered, int index, HPoint tile, HPoint movingTo,
HSign sign, HStance stance, HDirection headDirection, HDirection bodyDirection, HAction lastAction)
{
Index = index;
IsEmpowered = isEmpowered;
Tile = tile;
MovingTo = movingTo;
Sign = sign;
Stance = stance;
HeadDirection = headDirection;
BodyDirection = bodyDirection;
LastAction = lastAction;
}
/// <summary>
/// Returns a <see cref="IReadOnlyList{T}"/> of type <see cref="HEntityAction"/> found in the <see cref="HMessage"/>.
/// </summary>
/// <param name="packet">The <see cref="HMessage"/> that contains the <see cref="HEntityAction"/> data to parse.</param>
/// <returns></returns>
public static IReadOnlyList<HEntityAction> Parse(HPacket packet)
{
int entityActionCount = packet.ReadInt32();
var entityActionList = new List<HEntityAction>(entityActionCount);
for (int i = 0; i < entityActionList.Capacity; i++)
{
int index = packet.ReadInt32();
int x = packet.ReadInt32();
int y = packet.ReadInt32();
var z = double.Parse(packet.ReadUTF8(), CultureInfo.InvariantCulture);
var headDirection = (HDirection)packet.ReadInt32();
var bodyDirection = (HDirection)packet.ReadInt32();
string actionString = packet.ReadUTF8();
string[] actionData = actionString.Split(new[] { '/' },
StringSplitOptions.RemoveEmptyEntries);
HSign sign = HSign.One;
HAction action = HAction.None;
HStance stance = HStance.Stand;
double movingToZ = 0.0;
bool isEmpowered = false;
int movingToX = 0, movingToY = 0;
foreach (string actionInfo in actionData)
{
string[] actionValues = actionInfo.Split(' ');
if (actionValues.Length < 2) continue;
if (string.IsNullOrWhiteSpace(actionValues[0])) continue;
#region Switch: actionValues
switch (actionValues[0])
{
case "flatctrl":
{
isEmpowered = true;
break;
}
case "mv":
{
string[] movingToValues = actionValues[1].Split(',');
if (movingToValues.Length >= 3)
{
movingToX = int.Parse(movingToValues[0]);
movingToY = int.Parse(movingToValues[1]);
movingToZ = double.Parse(movingToValues[2], CultureInfo.InvariantCulture);
}
action = HAction.Move;
break;
}
case "sit":
{
action = HAction.Sit;
stance = HStance.Sit;
break;
}
case "lay":
{
action = HAction.Lay;
stance = HStance.Lay;
break;
}
case "sign":
{
sign = (HSign)int.Parse(actionValues[1]);
action = HAction.Sign;
break;
}
}
#endregion
}
var entityAction = new HEntityAction(isEmpowered, index, new HPoint(x, y, z),
new HPoint(movingToX, movingToY, movingToZ), sign, stance, headDirection, bodyDirection, action);
entityActionList.Add(entityAction);
}
return entityActionList;
}
/// <summary>
/// Converts the <see cref="HEntityAction"/> to a human-readable string.
/// </summary>
/// <returns></returns>
public override string ToString()
{
return $"{nameof(IsEmpowered)}: {IsEmpowered}, {nameof(Index)}: {Index}, {nameof(Tile)}: {Tile}, " +
$"{nameof(MovingTo)}: {MovingTo}, {nameof(HeadDirection)}: {HeadDirection}, " +
$"{nameof(BodyDirection)}: {BodyDirection}, {nameof(LastAction)}: {LastAction}";
}
}
}
\ No newline at end of file
using System.Globalization;
using System.Collections.Generic;
using Tangine.Habbo;
using Tangine.Network.Protocol;
namespace Sulakore.Habbo
{
public class HFurniture
{
public int Id { get; set; }
public int TypeId { get; set; }
public int OwnerId { get; set; }
public string OwnerName { get; set; }
public HPoint Tile { get; set; }
public HDirection Direction { get; set; }
public HFurniture(int id, int typeId, int ownerId,
string ownerName, HPoint tile, HDirection direction)
{
Id = id;
TypeId = typeId;
OwnerId = ownerId;
OwnerName = ownerName;
Tile = tile;
Direction = direction;
}
public static IReadOnlyList<HFurniture> Parse(HPacket packet)
{
int ownersCount = packet.ReadInt32();
var owners = new Dictionary<int, string>(ownersCount);
for (int i = 0; i < ownersCount; i++)
{
int ownerId = packet.ReadInt32();
string ownerName = packet.ReadUTF8();
owners.Add(ownerId, ownerName);
}
int furnitureCount = packet.ReadInt32();
var furnitureList = new List<HFurniture>(furnitureCount);
for (int i = 0; i < furnitureList.Capacity; i++)
{
int id = packet.ReadInt32();
int typeId = packet.ReadInt32();
int x = packet.ReadInt32();
int y = packet.ReadInt32();
var direction = (HDirection)packet.ReadInt32();
var z = double.Parse(packet.ReadUTF8(), CultureInfo.InvariantCulture);
packet.ReadUTF8();
packet.ReadInt32();
int category = packet.ReadInt32();
HStuffData.ReadStuffData(category, packet);
packet.ReadInt32();
packet.ReadInt32();
int ownerId = packet.ReadInt32();
if (typeId < 0) packet.ReadUTF8();
var furniture = new HFurniture(id, typeId, ownerId,
owners[ownerId], new HPoint(x, y, z), direction);
furnitureList.Add(furniture);
}
return furnitureList;
}
public override string ToString()
{
return $"{nameof(Id)}: {Id}, {nameof(TypeId)}: {TypeId}, " +
$"{nameof(OwnerId)}: {OwnerId}, {nameof(OwnerName)}: {OwnerName}";
}
}
}
\ No newline at end of file
using Tangine.Network.Protocol;
using System.Collections.Generic;
namespace Sulakore.Habbo
{
public class HItem
{
public int Id { get; set; }
public int TypeId { get; set; }
public int RoomId { get; set; }
public int Category { get; set; }
public string SlotId { get; set; }
public int SecondsToExpiration { get; set; }
public bool HasRentPeriodStarted { get; set; }
public HItem(int id, int typeId, int category,
int secondsToExpiration, bool hasRentPeriodStarted, int roomId)
{
Id = id;
TypeId = typeId;
Category = category;
SecondsToExpiration = secondsToExpiration;
HasRentPeriodStarted = hasRentPeriodStarted;
RoomId = roomId;
}
public static IReadOnlyList<HItem> Parse(HPacket packet)
{
packet.ReadInt32();
packet.ReadInt32();
int itemCount = packet.ReadInt32();
var itemList = new List<HItem>(itemCount);
for (int i = 0; i < itemList.Capacity; i++)
{
packet.ReadInt32();
string s1 = packet.ReadUTF8();
int id = packet.ReadInt32();
int typeId = packet.ReadInt32();
packet.ReadInt32();
int category = packet.ReadInt32();
HStuffData.ReadStuffData(category, packet);
packet.ReadBoolean();
packet.ReadBoolean();
packet.ReadBoolean();
packet.ReadBoolean();
int secondsToExpiration = packet.ReadInt32();
bool hasRentPeriodStarted = packet.ReadBoolean();
int roomId = packet.ReadInt32();
var item = new HItem(id, typeId, category,
secondsToExpiration, hasRentPeriodStarted, roomId);
if (s1 == "S")
{
item.SlotId = packet.ReadUTF8();
packet.ReadInt32();
}
itemList.Add(item);
}
return itemList;
}
public override string ToString()
{
return $"{nameof(Id)}: {Id}, {nameof(TypeId)}: {TypeId}, " +
$"{nameof(RoomId)}: {RoomId}, {nameof(Category)}: {Category}, {nameof(SlotId)}: {SlotId}, " +
$"{nameof(SecondsToExpiration)}: {SecondsToExpiration}, {nameof(HasRentPeriodStarted)}: {HasRentPeriodStarted}";
}
}
}
\ No newline at end of file
using System;
namespace Sulakore.Habbo
{
public class HMap
{
private readonly string[] _rows;
public int RowCount { get; }
public int TileCount { get; }
/// <summary>
/// Gets or sets the string representation of a row in the map.
/// </summary>
/// <param name="y">The y-coordinate of the row.</param>
/// <returns></returns>
public string this[int y]
{
get { return _rows[y]; }
set { _rows[y] = value.Substring(0, _rows[y].Length); }
}
/// <summary>
/// Gets or sets the UTF-16 character that represents the level in the three-dimensional plane.
/// </summary>
/// <param name="x">The x-coordinate in the plane.</param>
/// <param name="y">The y-coordinate in the plane.</param>
/// <returns></returns>
public char this[int x, int y]
{
get { return _rows[y][x]; }
set
{
_rows[y] = _rows[y].Remove(x, 1)
.Insert(x, value.ToString());
}
}
public HMap(string map)
{
map = Adjust(map);
_rows = map.Split(new[] { '\r' },
StringSplitOptions.RemoveEmptyEntries);
RowCount = _rows.Length;
TileCount = map.Length - RowCount;
}
public bool IsWalkable(HPoint tile)
{
return IsWalkable(tile.X, tile.Y);
}
public bool IsWalkable(int x, int y)
{
return this[x, y] != 'x';
}
public static string Adjust(string map)
{
map = map?.ToLower().Trim()
.Replace("\n", string.Empty)
.Replace("[13]", "\r") ?? string.Empty;
return map;
}
public override string ToString()
{
return string.Join("\r", _rows).Trim();
}
}
}
\ No newline at end of file
namespace Sulakore.Habbo
{
/// <summary>
/// Represents a floor object's in-game position relative to the map's three-dimensional plane.
/// </summary>
public class HPoint
{
/// <summary>
/// Gets or sets the x-coordinate of the <see cref="HPoint"/>.
/// </summary>
public int X { get; set; }
/// <summary>
/// Gets or sets the y-coordinate of the <see cref="HPoint"/>.
/// </summary>
public int Y { get; set; }
/// <summary>
/// Gets or sets the z-coordinate of the <see cref="HPoint"/>.
/// </summary>
public double Z { get; set; }
/// <summary>
/// Initializes a new instance of the <see cref="HPoint"/> class with the specified floor object coordinates.
/// </summary>
/// <param name="x">The horizontal position of the floor object.</param>
/// <param name="y">The vertical position of the floor object.</param>
public HPoint(int x, int y)
: this(x, y, 0.0)
{ }
/// <summary>
/// Initializes a new instance of the <see cref="HPoint"/> class with the specified floor object coordinates.
/// </summary>
/// <param name="x">The horizontal position of the floor object.</param>
/// <param name="y">The vertical position of the floor object.</param>
/// <param name="z">The elevated position of the floor object.</param>
public HPoint(int x, int y, double z)
{
X = x;
Y = y;
Z = z;
}
/// <summary>
/// Initializes a new instance of the <see cref="HPoint"/> class with the specified floor object coordinates.
/// </summary>
/// <param name="x">The horizontal position of the floor object.</param>
/// <param name="y">The vertical position of the floor object.</param>
/// <param name="level">The UTF-16 character that represent a floor level in the room map.</param>
public HPoint(int x, int y, char level)
: this(x, y, ToZ(level))
{ }
public static double ToZ(char level)
{
if (level >= '0' && level <= '9')
{
return (level - 48);
}
else if (level >= 'a' && level <= 't')
{
return (level - 87);
}
return 0;
}
public static char ToLevel(double z)
{
char level = 'x';
if (z >= 0 && z <= 9)
{
level = (char)(z + 48);
}
else if (z >= 10 && z <= 29)
{
level = (char)(z + 87);
}
return level;
}
/// <summary>
/// Converts the <see cref="HPoint"/> to a human-readable string.
/// </summary>
/// <returns></returns>
public override string ToString() =>
$"X: {X}, Y: {Y}, Z: {Z}";
}
}
\ No newline at end of file
using Tangine.Network.Protocol;
namespace Sulakore.Habbo
{
public static class HStuffData
{
public static void ReadStuffData(int category, HPacket packet)
{
switch (category & 255)
{
case 0:
{
packet.ReadUTF8();
break;
}
case 1: /* MapStuffData */
{
int count = packet.ReadInt32();
for (int j = 0; j < count; j++)
{
packet.ReadUTF8();
packet.ReadUTF8();
}
break;
}
case 2: /* StringArrayStuffData */
{
int count = packet.ReadInt32();
for (int j = 0; j < count; j++)
{
packet.ReadUTF8();
}
break;
}
case 3:
{
packet.ReadUTF8();
packet.ReadInt32();
break;
}
case 5: /* IntArrayStuffData */
{
int count = packet.ReadInt32();
for (int j = 0; j < count; j++)
{
packet.ReadInt32();
}
break;
}
case 6: /* HighScoreStuffData */
{
packet.ReadUTF8();
packet.ReadInt32();
packet.ReadInt32();
int count = packet.ReadInt32();
for (int j = 0; j < count; j++)
{
int score = packet.ReadInt32();
int subCount = packet.ReadInt32();
for (int k = 0; k < subCount; k++)
{
packet.ReadUTF8();
}
}
break;
}
case 7:
{
packet.ReadUTF8();
packet.ReadInt32();
packet.ReadInt32();
break;
}
}
}
}
}
\ No newline at end of file
namespace Sulakore.Habbo
{
/// <summary>
/// Represents an in-game object that provides a unique identifier relative to the room.
/// </summary>
public interface IHEntity
{
/// <summary>
/// Gets or sets the room index value of the <see cref="IHEntity"/>.
/// </summary>
int Index { get; }
}
}
\ No newline at end of file
using Tanji.Helpers;
using Tanji.Services;
using Tanji.Testing;
using Tanji.Windows.Logger;
namespace Tanji.Windows.Main
......@@ -36,8 +35,6 @@ namespace Tanji.Windows.Main
if (App.Master != null)
{
_loggerView = new LoggerView();
// TODO: Remove after debugging.
var datBoi = new OhShitItsDatEggGrabberBoi();
}
}
......