Skip to content

Commit

Permalink
Add 474 Protocol (#25)
Browse files Browse the repository at this point in the history
  • Loading branch information
JayArrowz authored May 18, 2021
1 parent ee5b8f3 commit 12f629d
Show file tree
Hide file tree
Showing 67 changed files with 2,328 additions and 151 deletions.
7 changes: 4 additions & 3 deletions NetScape.Abstractions/Constants.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
using DotNetty.Common.Utilities;
using NetScape.Abstractions.Model;
using NetScape.Abstractions.Model.Game;

namespace NetScape.Abstractions
{
public class Constants
{
public static readonly int RegionSize = 8;
public static readonly int ArchiveCount = 9;
public static readonly AttributeKey<Player> PlayerAttributeKey = AttributeKey<Player>.ValueOf("Player");
public static int RegionSize { get; } = 8;
public static AttributeKey<Player> PlayerAttributeKey { get; } = AttributeKey<Player>.ValueOf("Player");
public static Position HomePosition { get; } = new Position(3333, 3333, 0);
}
}
7 changes: 6 additions & 1 deletion NetScape.Abstractions/Extensions/ByteBufferExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,15 @@ namespace NetScape.Abstractions.Extensions
public static class ByteBufferExtensions
{
public static string ReadString(this IByteBuffer buffer)
{
return ReadString(buffer, 10);
}

public static string ReadString(this IByteBuffer buffer, int terminator)
{
var strBldr = new StringBuilder();
int charByte;
while ((charByte = buffer.ReadByte()) != 10)
while ((charByte = buffer.ReadByte()) != terminator)
{
strBldr.Append((char)charByte);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using System.Collections.Generic;
using System.Linq;

namespace NetScape.Abstractions.Model.Game.Walking
namespace NetScape.Abstractions.Model.Game
{
public class WalkingQueueHandler
{
Expand Down
110 changes: 110 additions & 0 deletions NetScape.Abstractions/Login/DefaultLoginProcessor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
using Autofac;
using NetScape.Abstractions.FileSystem;
using NetScape.Abstractions.Interfaces.Login;
using NetScape.Abstractions.Model.Login;
using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace NetScape.Abstractions.Login
{
public abstract class DefaultLoginProcessor<TRequest, TResponse> : ILoginProcessor<TRequest, TResponse>,
IStartable,
IDisposable
where TRequest : LoginRequest<TResponse>
{
protected internal readonly ILogger _logger;
private readonly IList<TRequest> _loginRequests = new List<TRequest>();

private readonly object _lockObject = new object();

private CancellationToken _cancellationToken;
private CancellationTokenSource _cancellationTokenSource;

public DefaultLoginProcessor(ILogger logger)
{
_logger = logger;
}

/// <summary>
/// Enqueues the specified request.
/// </summary>
/// <param name="request">The request.</param>
/// <exception cref="InvalidOperationException">Login already exists</exception>
public void Enqueue(TRequest request)
{
lock (_lockObject)
{
var loginExists = _loginRequests.Any(t => t.Credentials.Username.Equals(request.Credentials.Username, StringComparison.InvariantCultureIgnoreCase)
&& t.Credentials.Password.Equals(request.Credentials.Password, StringComparison.InvariantCultureIgnoreCase));

if (loginExists)
{
throw new InvalidOperationException("Login already exists");
}

_loginRequests.Add(request);
}
}

/// <summary>
/// Processes a single by retriving the player from <see cref="IPlayerSerializer"/>
/// </summary>
/// <param name="request">The login request.</param>
/// <returns></returns>
protected abstract Task<TResponse> ProcessAsync(TRequest request);

/// <summary>
/// Handles the login queue
/// </summary>
private async Task ProcessLoginsAsync()
{
while (!_cancellationToken.IsCancellationRequested)
{
while (_loginRequests.Count > 0)
{
var requests = _loginRequests.ToList();
var tasks = requests.Select(loginTask =>
(request: loginTask, responseTask: ProcessAsync(loginTask)))
.ToList();
await Task.WhenAll(tasks.Select(t => t.responseTask));
tasks.ForEach(t =>
{
var responseTask = t.responseTask;
var request = t.request;
if (responseTask.IsCompletedSuccessfully)
{
_loginRequests.Remove(t.request);
t.request.Result = request.Result;
_ = request.OnResult(responseTask.Result);
_logger.Debug("Processed Login Request: {@LoginRequest}", request.Credentials);
}
});
}
await Task.Delay(600);
}
}

/// <summary>
/// Perform once-off startup processing.
/// </summary>
public void Start()
{
_cancellationTokenSource = new CancellationTokenSource();
_cancellationToken = _cancellationTokenSource.Token;
Task.Factory.StartNew(ProcessLoginsAsync, _cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Default);
}

/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
_cancellationTokenSource?.Cancel();
_cancellationTokenSource?.Dispose();
}
}
}
3 changes: 3 additions & 0 deletions NetScape.Abstractions/Model/Game/Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using NetScape.Abstractions.Model.World.Updating.Blocks;
using NetScape.Modules.Messages;
using NetScape.Modules.Messages.Builder;
using Serilog;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Threading;
Expand All @@ -17,6 +18,7 @@ public partial class Player : Mob
private static readonly int DefaultViewingDistance = 15;
private static int _appearanceTicketCounter = 0;

[NotMapped] public int PingCount { get; set; }
[NotMapped] public Position LastKnownRegion { get; set; }
[NotMapped] public bool RegionChanged { get; set; }
[NotMapped] public int AppearanceTicket { get; } = NextAppearanceTicket();
Expand Down Expand Up @@ -66,6 +68,7 @@ public void ResetViewingDistance()
/// <param name="message">The message.</param>
public async Task SendAsync(IEncoderMessage<MessageFrame> message)
{
Log.Logger.Debug("Sending {0} to player {1}", message, Username);
var msg = message.ToMessage(ChannelHandlerContext.Allocator);

if (ChannelHandlerContext.Channel.Active)
Expand Down
7 changes: 7 additions & 0 deletions NetScape.Abstractions/Model/Login/LoginRequest.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using DotNetty.Transport.Channels;
using NetScape.Abstractions.IO.Util;
using System;
using System.Threading.Tasks;

namespace NetScape.Abstractions.Model.Login
{
Expand All @@ -19,5 +21,10 @@ public record LoginRequest<TRes>

public int ReleaseNumber { get; set; }
public TRes Result { get; set; }

/// <summary>
/// Called on response of request <seealso cref="LoginProcessor.ProcessLoginsAsync"/>
/// </summary>
public Func<TRes, Task> OnResult { get; set; }
}
}
18 changes: 18 additions & 0 deletions NetScape.Abstractions/Model/Position.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,24 @@ public int TopLeftRegionY
}
}

/// <summary>
/// Gets the region x.
/// </summary>
/// <value>
/// The region x.
/// </value>
[NotMapped]
public int RegionX => (X >> 3) - 6;

/// <summary>
/// Gets the region y.
/// </summary>
/// <value>
/// The region y.
/// </value>
[NotMapped]
public int RegionY => (Y >> 3) - 6;

/// <summary>
/// Gets the x coordinate.
/// </summary>
Expand Down
1 change: 1 addition & 0 deletions NetScape.Abstractions/NetScape.Abstractions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Abstractions" Version="5.0.1" />
<PackageReference Include="Nito.Collections.Deque" Version="1.1.0" />
<PackageReference Include="Portable.BouncyCastle" Version="1.8.9" />
<PackageReference Include="Serilog" Version="2.10.0" />
<PackageReference Include="SevenZip" Version="19.0.0" />
<PackageReference Include="SharpZipLib" Version="1.3.1" />
<PackageReference Include="System.Linq" Version="4.3.0" />
Expand Down
2 changes: 1 addition & 1 deletion NetScape.Modules.Cache/RuneTek5/Sector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public static Sector Decode(int position, byte[] data, CacheIndex expectedIndex,
var nextSectorPosition = dataReader.ReadUInt24BigEndian();

var actualIndex = (CacheIndex)dataReader.ReadByte();
if (actualIndex - 1 != expectedIndex)
if (actualIndex != expectedIndex)
{
throw new DecodeException($"Expected sector for index {(int)expectedIndex}, got {(int)actualIndex}.");
}
Expand Down
4 changes: 1 addition & 3 deletions NetScape.Modules.DAL.Test/NetScape.Modules.DAL.Test.csproj
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp5.0</TargetFramework>

<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
Expand Down
3 changes: 2 additions & 1 deletion NetScape.Modules.DAL/EntityFrameworkPlayerSerializer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.EntityFrameworkCore;
using NetScape.Abstractions;
using NetScape.Abstractions.FileSystem;
using NetScape.Abstractions.Model;
using NetScape.Abstractions.Model.Game;
Expand Down Expand Up @@ -80,7 +81,7 @@ public async Task<Player> GetOrCreateAsync(PlayerCredentials playerCredentials)
{
Username = playerCredentials.Username,
Password = playerCredentials.Password,
Position = new Position(3333, 3333, 0),
Position = Constants.HomePosition,
Appearance = Appearance.DefaultAppearance
};
dbContext.Attach(defaultPlayer);
Expand Down
31 changes: 31 additions & 0 deletions NetScape.Modules.FourSevenFour.Game/FourSevenFourGameModule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Autofac;
using NetScape.Abstractions.Interfaces.Game.Interface;
using NetScape.Abstractions.Interfaces.Game.Player;
using NetScape.Abstractions.Interfaces.Messages;
using NetScape.Modules.FourSevenFour.Game.Interface;
using NetScape.Modules.FourSevenFour.Game.Players;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NetScape.Modules.FourSevenFour.Game
{
public class FourSevenFourGameModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<TabManager>().As<ITabManager>();
builder.RegisterType<PlayerInitializer>().As<IPlayerInitializer>();

#region Handlers
builder.RegisterAssemblyTypes(typeof(FourSevenFourGameModule).Assembly)
.AsClosedTypesOf(typeof(IMessageDecoder<>))
.As<IMessageDecoder>()
.SingleInstance();
#endregion
base.Load(builder);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using NetScape.Abstractions.Model;
using NetScape.Abstractions.Model.Game;
using NetScape.Modules.Messages;
using NetScape.Modules.Messages.Builder;
using NetScape.Modules.Messages.Models;
using System.Linq;

namespace NetScape.Modules.FourSevenFour.Game.Messages.Decoders
{
public class WalkingQueueMessageDecoder : MessageDecoderBase<FourSevenFourDecoderMessages.Types.WalkingQueueMessage>
{
public override int[] Ids { get; } = new int[] { 11, 46, 59 };
public override FrameType FrameType { get; } = FrameType.VariableByte;

protected override FourSevenFourDecoderMessages.Types.WalkingQueueMessage Decode(Player player, MessageFrame frame)
{
var reader = new MessageFrameReader(frame);
var length = frame.Payload.ReadableBytes;

if (frame.Id == 11)
{
length -= 14; // strip off anti-cheat data
}

int steps = (length - 5) / 2;
int[,] path = new int[steps, 2];
for (int i = 0; i < steps; i++)
{
path[i, 0] = (int)reader.GetSigned(MessageType.Byte);
path[i, 1] = (int)reader.GetSigned(MessageType.Byte, DataTransformation.Subtract);
}
int x = (int)reader.GetUnsigned(MessageType.Short, DataTransformation.Add);
int y = (int)reader.GetUnsigned(MessageType.Short, DataOrder.Little);
var run = reader.GetUnsigned(MessageType.Byte, DataTransformation.Negate) == 1;

var positions = new Position[steps + 1];
positions[0] = new Position(x, y);
for (int i = 0; i < steps; i++)
{
positions[i + 1] = new Position(path[i, 0] + x, path[i, 1] + y);
}
FourSevenFourDecoderMessages.Types.WalkingQueueMessage walkingQueueMessage = new() { Run = run, };
walkingQueueMessage.X.Add(positions.Select(t => t.X));
walkingQueueMessage.Y.Add(positions.Select(t => t.Y));
return walkingQueueMessage;
}
}
}
Loading

0 comments on commit 12f629d

Please sign in to comment.