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

Release bugfixes #224

Merged
merged 30 commits into from Sep 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
c47e2d6
Use ConcurrentDictionary in NativeGraphicsManager instead of locking …
ethanmoffat Sep 16, 2022
02bb182
Update detection for stacked characters to consider character draw ar…
ethanmoffat Sep 16, 2022
3dcda22
Support clicking to open doors
ethanmoffat Sep 16, 2022
bf737a2
Add door validation for click to open and fix character taking a step…
ethanmoffat Sep 16, 2022
d0db16d
Unset selected spell when clicking on a non-target. Make map sign dia…
ethanmoffat Sep 17, 2022
255afc1
Make clicking an object after clicking to walk cancel the walk path
ethanmoffat Sep 17, 2022
6428220
Split MESSAGE_ACCEPT single string messages at 68 spaces.
ethanmoffat Sep 17, 2022
2194fa2
Calculate Top/Bottom pixel of NPCs correctly. Add check for visible p…
ethanmoffat Sep 18, 2022
42eee0a
Extract UnwalkableTileActionsHandler from ArrowKeyController
ethanmoffat Sep 18, 2022
59b71f4
Fix replaying a walk into walls/NPCs bumping the character back
ethanmoffat Sep 18, 2022
f80b3b0
Update README
ethanmoffat Sep 19, 2022
ebc8f06
Fix bug where idling at initial screen for a while and then logging i…
ethanmoffat Sep 19, 2022
b22aada
Jump tiles play SFX when clicking to walk
ethanmoffat Sep 19, 2022
457634c
Fix bug where replaying a walk after turning when you would have hit …
ethanmoffat Sep 19, 2022
34a159a
Ensure walking NPCs are rendered as part of the correct row/col
ethanmoffat Sep 19, 2022
7b603e6
Render NPCs a little earlier on the map (one row/col higher). Fixes r…
ethanmoffat Sep 19, 2022
3d932d8
Fix email regex for account creation to accept all 2-letter domains. …
ethanmoffat Sep 19, 2022
41311c8
Ensure empty news text does not show an empty message with the string…
ethanmoffat Sep 19, 2022
663e50a
Make sure chat panel is set as the default panel if there is no news …
ethanmoffat Sep 19, 2022
d968292
Fix mouseover check for irregularly sized NPC texture sets. Fixes bug…
ethanmoffat Sep 19, 2022
3f2b1a3
Fix bug in default panel display
ethanmoffat Sep 19, 2022
478be4e
Revert "Render NPCs a little earlier on the map (one row/col higher).…
ethanmoffat Sep 19, 2022
6676c84
Increase render distance for Overlay layer. Fixes large overlay tiles…
ethanmoffat Sep 19, 2022
bdb8ce4
Fix bug in data encoder where MSB of 128 and 0 value bytes was errone…
ethanmoffat Sep 20, 2022
5433ead
Ensure map renderer does not render the same map coordinate twice. Th…
ethanmoffat Sep 20, 2022
c12bd67
Handle dialog open packets that were not initiated client-side
ethanmoffat Sep 20, 2022
0d30778
Update input handling to back off when completing a warp. Fixes some …
ethanmoffat Sep 20, 2022
c4d244c
Fix map edge rendering in MiniMapRenderer. Fix interaction with Unkno…
ethanmoffat Sep 20, 2022
227bb8d
Fix frame update timing for release builds (limit to 60 updates/second)
ethanmoffat Sep 20, 2022
4d8e64c
Update XNAControls to latest version. Set MaxWidth on chat text box s…
ethanmoffat Sep 20, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
44 changes: 16 additions & 28 deletions EOLib.Graphics/NativeGraphicsManager.cs
@@ -1,28 +1,26 @@
using System;
using System.Collections.Generic;
using System.IO;
using AutomaticTypeMapper;
using AutomaticTypeMapper;
using Microsoft.Xna.Framework.Graphics;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using System;
using System.Collections.Concurrent;
using System.IO;

namespace EOLib.Graphics
{
[MappedType(BaseType = typeof(INativeGraphicsManager), IsSingleton = true)]
public sealed class NativeGraphicsManager : INativeGraphicsManager
{
private readonly Dictionary<LibraryGraphicPair, Texture2D> _cache;
private readonly object __cachelock__ = new object();
private readonly ConcurrentDictionary<LibraryGraphicPair, Texture2D> _cache;

private readonly INativeGraphicsLoader _gfxLoader;
private readonly IGraphicsDeviceProvider _graphicsDeviceProvider;

public NativeGraphicsManager(INativeGraphicsLoader gfxLoader, IGraphicsDeviceProvider graphicsDeviceProvider)
{
_cache = new Dictionary<LibraryGraphicPair, Texture2D>();
_cache = new ConcurrentDictionary<LibraryGraphicPair, Texture2D>();
_gfxLoader = gfxLoader;
_graphicsDeviceProvider = graphicsDeviceProvider;
}
Expand All @@ -33,17 +31,16 @@ public Texture2D TextureFromResource(GFXTypes file, int resourceVal, bool transp

var key = new LibraryGraphicPair((int)file, 100 + resourceVal);

lock (__cachelock__)
if (_cache.ContainsKey(key))
{
if (!reloadFromFile && _cache.ContainsKey(key))
if (reloadFromFile)
{
return _cache[key];
_cache[key]?.Dispose();
_cache.TryRemove(key, out var _);
}

if (_cache.ContainsKey(key) && reloadFromFile)
else
{
if (_cache[key] != null) _cache[key].Dispose();
_cache.Remove(key);
return _cache[key];
}
}

Expand All @@ -64,11 +61,7 @@ public Texture2D TextureFromResource(GFXTypes file, int resourceVal, bool transp
}
}

lock (__cachelock__)
{
_cache.Add(key, ret);
}

_cache.TryAdd(key, ret);
return ret;
}

Expand Down Expand Up @@ -103,14 +96,9 @@ private static void CrossPlatformMakeTransparent(Image bmp, Color transparentCol

public void Dispose()
{
lock (__cachelock__)
{
foreach (var text in _cache.Values)
{
text.Dispose();
}
_cache.Clear();
}
foreach (var text in _cache.Values)
text.Dispose();
_cache.Clear();
}
}

Expand Down
4 changes: 2 additions & 2 deletions EOLib.IO/NumericConstants.cs
Expand Up @@ -6,8 +6,8 @@ namespace EOLib.IO
public static class NumericConstants
{
public const int ONE_BYTE_MAX = 253;
public const int TWO_BYTE_MAX = 64009;
public const int THREE_BYTE_MAX = 16194277;
public const int TWO_BYTE_MAX = ONE_BYTE_MAX * ONE_BYTE_MAX;
public const int THREE_BYTE_MAX = ONE_BYTE_MAX * ONE_BYTE_MAX * ONE_BYTE_MAX;

public static readonly int[] NUMERIC_MAXIMUM = {ONE_BYTE_MAX, TWO_BYTE_MAX, THREE_BYTE_MAX };
}
Expand Down
2 changes: 1 addition & 1 deletion EOLib.IO/Services/DataEncoderService.cs
Expand Up @@ -59,7 +59,7 @@ public List<byte> Deinterleave(IReadOnlyList<byte> data)

public List<byte> FlipMSB(IReadOnlyList<byte> data)
{
return data.Select(x => (byte)(x ^ 0x80u)).ToList();
return data.Select(x => (byte)(x == 128 || x == 0 ? x : x ^ 0x80u)).ToList();
}

public List<byte> SwapMultiples(IReadOnlyList<byte> data, int multi)
Expand Down
45 changes: 45 additions & 0 deletions EOLib.Test/Net/PacketEncoderServiceTest.cs
@@ -0,0 +1,45 @@
using EOLib.Domain.Interact.Quest;
using EOLib.IO.Services;
using EOLib.Net;
using EOLib.Net.PacketProcessing;
using NUnit.Framework;

namespace EOLib.IO.Test.Services
{
[TestFixture]
public class PacketEncoderServiceTest
{
[Test]
public void PacketEncoderService_Encode_127Byte_DoesNotProduceAny0ValueBytes()
{
var svc = new PacketEncoderService(new NumberEncoderService(), new DataEncoderService());

var packet = new PacketBuilder(PacketFamily.Quest, PacketAction.Accept)
.AddShort(0)
.AddShort(0)
.AddShort(111)
.AddShort(127)
.AddChar((byte)DialogReply.Link)
.AddChar(1)
.Build();

var encoded = svc.Encode(packet, 5);

Assert.That(encoded, Has.All.Not.EqualTo(0));
}

[Test]
public void PacketEncoderService_Encode_0Byte_DoesNotProduceAny128ValueBytes()
{
var svc = new PacketEncoderService(new NumberEncoderService(), new DataEncoderService());

var packet = new PacketBuilder(PacketFamily.Quest, PacketAction.Accept)
.AddByte(0)
.Build();

var encoded = svc.Encode(packet, 5);

Assert.That(encoded, Has.All.Not.EqualTo(128));
}
}
}
4 changes: 2 additions & 2 deletions EOLib/Domain/Account/CreateAccountParameterValidator.cs
Expand Up @@ -6,7 +6,7 @@ namespace EOLib.Domain.Account
[AutoMappedType]
public class CreateAccountParameterValidator : ICreateAccountParameterValidator
{
private const string ValidEmailRegex = @"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|asia|jobs|museum)\b";
private const string ValidEmailRegex = @"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[a-z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|asia|jobs|museum)\b";

public bool AccountNameIsNotLongEnough(string account)
{
Expand Down Expand Up @@ -35,7 +35,7 @@ public bool PasswordIsTooObvious(string password)

public bool EmailIsInvalid(string email)
{
return !System.Text.RegularExpressions.Regex.IsMatch(email, ValidEmailRegex);
return !System.Text.RegularExpressions.Regex.IsMatch(email.ToLowerInvariant(), ValidEmailRegex);
}
}

Expand Down
4 changes: 3 additions & 1 deletion EOLib/Domain/Character/WalkValidationActions.cs
Expand Up @@ -114,7 +114,9 @@ private static bool IsTileSpecWalkable(TileSpec tileSpec)
case TileSpec.None:
return true;
default:
return false;
// These values were tested with the Vanilla 0.28 client
// TileSpec 10, 12, and 31 are walkable while other unknown values are not
return (int)tileSpec == 10 || (int)tileSpec == 12 || (int)tileSpec == 31;
}
}
}
Expand Down
@@ -1,5 +1,6 @@
using System.Linq;
using EOLib.Domain.Character;
using EOLib.Domain.Map;

namespace EOLib.Domain.Extensions
{
Expand Down Expand Up @@ -113,5 +114,7 @@ public static CharacterRenderProperties ResetAnimationFrames(this CharacterRende
props.CurrentAction = props.SitState == SitState.Standing ? CharacterActionState.Standing : CharacterActionState.Sitting;
return props.ToImmutable();
}

public static MapCoordinate Coordinates(this CharacterRenderProperties rp) => new MapCoordinate(rp.MapX, rp.MapY);
}
}
7 changes: 7 additions & 0 deletions EOLib/Domain/Map/CurrentMapStateRepository.cs
@@ -1,5 +1,6 @@
using AutomaticTypeMapper;
using Optional;
using System;
using System.Collections.Generic;

namespace EOLib.Domain.Map
Expand Down Expand Up @@ -30,6 +31,8 @@ public interface ICurrentMapStateRepository

Option<short> MapWarpID { get; set; }

Option<DateTime> MapWarpTime { get; set; }

HashSet<short> UnknownPlayerIDs { get; set; }

HashSet<byte> UnknownNPCIndexes { get; set; }
Expand Down Expand Up @@ -61,6 +64,8 @@ public interface ICurrentMapStateProvider

Option<short> MapWarpID { get; }

Option<DateTime> MapWarpTime { get; }

HashSet<short> UnknownPlayerIDs { get; }

HashSet<byte> UnknownNPCIndexes { get; }
Expand Down Expand Up @@ -93,6 +98,8 @@ public class CurrentMapStateRepository : ICurrentMapStateRepository, ICurrentMap

public Option<short> MapWarpID { get; set; }

public Option<DateTime> MapWarpTime { get; set; }

public HashSet<short> UnknownPlayerIDs { get; set; }

public HashSet<byte> UnknownNPCIndexes { get; set; }
Expand Down
3 changes: 3 additions & 0 deletions EOLib/Domain/Map/MapActions.cs
Expand Up @@ -51,6 +51,9 @@ public ItemPickupResult PickUpItem(MapItem item)

public void OpenDoor(Warp warp)
{
if (_currentMapStateRepository.PendingDoors.Contains(warp))
return;

var packet = new PacketBuilder(PacketFamily.Door, PacketAction.Open)
.AddChar((byte)warp.X)
.AddChar((byte)warp.Y)
Expand Down
5 changes: 5 additions & 0 deletions EOLib/Domain/Notifiers/IUserInterfaceNotifier.cs
@@ -1,16 +1,21 @@
using AutomaticTypeMapper;
using EOLib.Net;
using System.Collections.Generic;

namespace EOLib.Domain.Notifiers
{
public interface IUserInterfaceNotifier
{
void NotifyPacketDialog(PacketFamily packetFamily);

void NotifyMessageDialog(string title, IReadOnlyList<string> messages);
}

[AutoMappedType]
public class NoOpUserInterfaceNotifier : IUserInterfaceNotifier
{
public void NotifyPacketDialog(PacketFamily packetFamily) { }

public void NotifyMessageDialog(string title, IReadOnlyList<string> messages) { }
}
}
11 changes: 9 additions & 2 deletions EOLib/PacketHandlers/Chest/ChestOpenHandler.cs
@@ -1,26 +1,30 @@
using AutomaticTypeMapper;
using EOLib.Domain.Character;
using EOLib.Domain.Login;
using EOLib.Domain.Map;
using EOLib.Domain.Notifiers;
using EOLib.Net;
using EOLib.Net.Handlers;
using System.Collections.Generic;

namespace EOLib.PacketHandlers.Chest
{
[AutoMappedType]
public class ChestOpenHandler : InGameOnlyPacketHandler
{
private readonly IChestDataRepository _chestDataRepository;
private readonly IEnumerable<IUserInterfaceNotifier> _userInterfaceNotifiers;

public override PacketFamily Family => PacketFamily.Chest;

public override PacketAction Action => PacketAction.Open;

public ChestOpenHandler(IPlayerInfoProvider playerInfoProvider,
IChestDataRepository chestDataRepository)
IChestDataRepository chestDataRepository,
IEnumerable<IUserInterfaceNotifier> userInterfaceNotifiers)
: base(playerInfoProvider)
{
_chestDataRepository = chestDataRepository;
_userInterfaceNotifiers = userInterfaceNotifiers;
}

public override bool HandlePacket(IPacket packet)
Expand All @@ -35,6 +39,9 @@ public override bool HandlePacket(IPacket packet)
while (packet.ReadPosition < packet.Length)
_chestDataRepository.Items.Add(new ChestItem(packet.ReadShort(), packet.ReadThree(), i++));

foreach (var notifier in _userInterfaceNotifiers)
notifier.NotifyPacketDialog(Family);

return true;
}
}
Expand Down
6 changes: 5 additions & 1 deletion EOLib/PacketHandlers/EndPlayerWarpHandler.cs
Expand Up @@ -10,6 +10,8 @@
using EOLib.Net;
using EOLib.Net.Handlers;
using EOLib.Net.Translators;
using Optional;
using System;
using System.Collections.Generic;
using System.Linq;

Expand Down Expand Up @@ -52,6 +54,8 @@ public override bool HandlePacket(IPacket packet)

var warpAgreePacketData = _warpAgreePacketTranslator.TranslatePacket(packet);

_currentMapStateRepository.CurrentMapID = warpAgreePacketData.MapID;

var updatedMainCharacter = warpAgreePacketData.Characters.Single(MainCharacterIDMatches);

//character.renderproperties.isdead is set True by the attack handler
Expand All @@ -66,7 +70,6 @@ public override bool HandlePacket(IPacket packet)

var differentMapID = _currentMapStateRepository.CurrentMapID != warpAgreePacketData.MapID;

_currentMapStateRepository.CurrentMapID = warpAgreePacketData.MapID;
_currentMapStateRepository.Characters = warpAgreePacketData.Characters.ToDictionary(k => k.ID, v => v);
_currentMapStateRepository.NPCs = new HashSet<NPC>(warpAgreePacketData.NPCs);
_currentMapStateRepository.MapItems = new HashSet<MapItem>(warpAgreePacketData.Items);
Expand All @@ -80,6 +83,7 @@ public override bool HandlePacket(IPacket packet)
warpAnimation: warpAgreePacketData.WarpAnimation);

_currentMapStateRepository.MapWarpState = WarpState.None;
_currentMapStateRepository.MapWarpTime = Option.Some(DateTime.Now);

return true;
}
Expand Down
10 changes: 9 additions & 1 deletion EOLib/PacketHandlers/Locker/LockerOpenHandler.cs
Expand Up @@ -2,8 +2,10 @@
using EOLib.Domain.Character;
using EOLib.Domain.Login;
using EOLib.Domain.Map;
using EOLib.Domain.Notifiers;
using EOLib.Net;
using EOLib.Net.Handlers;
using System.Collections.Generic;

namespace EOLib.PacketHandlers.Locker
{
Expand All @@ -14,16 +16,19 @@ namespace EOLib.PacketHandlers.Locker
public class LockerOpenHandler : InGameOnlyPacketHandler
{
private readonly ILockerDataRepository _lockerDataRepository;
private readonly IEnumerable<IUserInterfaceNotifier> _userInterfaceNotifiers;

public override PacketFamily Family => PacketFamily.Locker;

public override PacketAction Action => PacketAction.Open;

public LockerOpenHandler(IPlayerInfoProvider playerInfoProvider,
ILockerDataRepository lockerDataRepository)
ILockerDataRepository lockerDataRepository,
IEnumerable<IUserInterfaceNotifier> userInterfaceNotifiers)
: base(playerInfoProvider)
{
_lockerDataRepository = lockerDataRepository;
_userInterfaceNotifiers = userInterfaceNotifiers;
}

public override bool HandlePacket(IPacket packet)
Expand All @@ -37,6 +42,9 @@ public override bool HandlePacket(IPacket packet)
while (packet.ReadPosition < packet.Length)
_lockerDataRepository.Items.Add(new InventoryItem(packet.ReadShort(), packet.ReadThree()));

foreach (var notifier in _userInterfaceNotifiers)
notifier.NotifyPacketDialog(Family);

return true;
}
}
Expand Down