Skip to content

Commit

Permalink
Merge pull request #206 from ethanmoffat/partygroup
Browse files Browse the repository at this point in the history
Implement party/group
  • Loading branch information
ethanmoffat authored Jun 14, 2022
2 parents b047960 + 8c9d15f commit 434d599
Show file tree
Hide file tree
Showing 52 changed files with 1,195 additions and 834 deletions.
13 changes: 13 additions & 0 deletions EOBot/Interpreter/BuiltInIdentifierConfigurator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using EOLib.Domain.Login;
using EOLib.Domain.Map;
using EOLib.Domain.NPC;
using EOLib.Domain.Party;
using EOLib.Domain.Protocol;
using EOLib.IO.Repositories;
using EOLib.Net.Communication;
Expand Down Expand Up @@ -45,6 +46,8 @@ public void SetupBuiltInFunctions()
_state.SymbolTable[PredefinedIdentifiers.SETENV_FUNC] = Readonly(new VoidFunction<string, string>(PredefinedIdentifiers.SETENV_FUNC, (varName, varValue) => Environment.SetEnvironmentVariable(varName, varValue, EnvironmentVariableTarget.User)));
_state.SymbolTable[PredefinedIdentifiers.GETENV_FUNC] = Readonly(new Function<string, string>(PredefinedIdentifiers.GETENV_FUNC, varName => Environment.GetEnvironmentVariable(varName, EnvironmentVariableTarget.User)));
_state.SymbolTable[PredefinedIdentifiers.ERROR_FUNC] = Readonly(new VoidFunction<string>(PredefinedIdentifiers.ERROR_FUNC, message => throw new BotScriptErrorException(message)));
_state.SymbolTable[PredefinedIdentifiers.LOWER_FUNC] = Readonly(new Function<string, string>(PredefinedIdentifiers.LOWER_FUNC, s => s.ToLower()));
_state.SymbolTable[PredefinedIdentifiers.UPPER_FUNC] = Readonly(new Function<string, string>(PredefinedIdentifiers.UPPER_FUNC, s => s.ToUpper()));

BotDependencySetup();
_state.SymbolTable[PredefinedIdentifiers.CONNECT_FUNC] = Readonly(new AsyncVoidFunction<string, int>(PredefinedIdentifiers.CONNECT_FUNC, ConnectAsync));
Expand All @@ -56,7 +59,9 @@ public void SetupBuiltInFunctions()
_state.SymbolTable[PredefinedIdentifiers.CREATE_CHARACTER_FUNC] = Readonly(new AsyncFunction<string, int>(PredefinedIdentifiers.CREATE_CHARACTER_FUNC, CreateCharacterAsync));
_state.SymbolTable[PredefinedIdentifiers.DELETE_CHARACTER_FUNC] = Readonly(new AsyncFunction<string, bool, int>(PredefinedIdentifiers.DELETE_CHARACTER_FUNC, DeleteCharacterAsync));
_state.SymbolTable[PredefinedIdentifiers.LOGIN_CHARACTER_FUNC] = Readonly(new AsyncVoidFunction<string>(PredefinedIdentifiers.LOGIN_CHARACTER_FUNC, LoginToCharacterAsync));
_state.SymbolTable[PredefinedIdentifiers.JOIN_PARTY] = Readonly(new VoidFunction<int>(PredefinedIdentifiers.JOIN_PARTY, JoinParty));
}

public void SetupBuiltInVariables()
{
_state.SymbolTable[PredefinedIdentifiers.HOST] = Readonly(new StringVariable(_parsedArgs.Host));
Expand Down Expand Up @@ -175,6 +180,12 @@ private Task LoginToCharacterAsync(string charName)
return _botHelper.LoginToCharacterAsync(charName);
}

private void JoinParty(int characterId)
{
var c = DependencyMaster.TypeRegistry[_botIndex];
c.Resolve<IPartyActions>().RequestParty(PartyRequestType.Join, (short)characterId);
}

private (bool, IIdentifiable) SetupAccountObject()
{
var playerInfoProv = DependencyMaster.TypeRegistry[_botIndex].Resolve<IPlayerInfoProvider>();
Expand All @@ -201,6 +212,7 @@ private Task LoginToCharacterAsync(string charName)
var pubProvider = DependencyMaster.TypeRegistry[_botIndex].Resolve<IPubFileProvider>();

var charObj = new RuntimeEvaluatedMemberObjectVariable();
charObj.SymbolTable["id"] = (true, () => new IntVariable(cp.MainCharacter.ID));
charObj.SymbolTable[PredefinedIdentifiers.NAME] = (true, () => new StringVariable(cp.MainCharacter.Name));
charObj.SymbolTable["map"] = (true, () => new IntVariable(cp.MainCharacter.MapID));
charObj.SymbolTable["x"] = (true, () => new IntVariable(cp.MainCharacter.RenderProperties.MapX));
Expand Down Expand Up @@ -261,6 +273,7 @@ private Task LoginToCharacterAsync(string charName)
private IVariable GetMapStateCharacter(Character c)
{
var charObj = new ObjectVariable();
charObj.SymbolTable["id"] = Readonly(new IntVariable(c.ID));
charObj.SymbolTable[PredefinedIdentifiers.NAME] = Readonly(new StringVariable(c.Name));
charObj.SymbolTable["map"] = Readonly(new IntVariable(c.MapID));
charObj.SymbolTable["x"] = Readonly(new IntVariable(c.RenderProperties.MapX));
Expand Down
4 changes: 4 additions & 0 deletions EOBot/Interpreter/Variables/PredefinedIdentifiers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ public static class PredefinedIdentifiers
public const string SETENV_FUNC = "setenv";
public const string GETENV_FUNC = "getenv";
public const string ERROR_FUNC = "error";
public const string LOWER_FUNC = "lower";
public const string UPPER_FUNC = "upper";

// game functions
public const string CONNECT_FUNC = "Connect";
Expand All @@ -42,5 +44,7 @@ public static class PredefinedIdentifiers
public const string CREATE_CHARACTER_FUNC = "CreateCharacter";
public const string LOGIN_CHARACTER_FUNC = "LoginCharacter";
public const string DELETE_CHARACTER_FUNC = "DeleteCharacter";

public const string JOIN_PARTY = "JoinParty";
}
}
3 changes: 3 additions & 0 deletions EOBot/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
using EOLib.Domain.Map;
using EOLib.Domain.Notifiers;
using EOLib.Domain.NPC;
using EOLib.Domain.Spells;
using EOLib.IO.Repositories;
using Optional;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

Expand Down Expand Up @@ -160,6 +162,7 @@ public void NotifyStartSpellCast(short playerId, short spellId) { }
public void NotifyTargetOtherSpellCast(short sourcePlayerID, short targetPlayerID, short spellId, int recoveredHP, byte targetPercentHealth) { }
public void StartOtherCharacterAttackAnimation(int characterID, int noteIndex) { }
public void StartOtherCharacterWalkAnimation(int characterID, byte destinationX, byte destinationY, EODirection direction) { }
public void NotifyGroupSpellCast(short playerId, short spellId, short spellHp, List<GroupSpellTarget> spellTargets) { }
}

static async Task<int> Main(string[] args)
Expand Down
1 change: 0 additions & 1 deletion EOLib/Domain/Character/CharacterActions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,6 @@ public void CastSpell(int spellId, ISpellTargetable target)

if (data.Target == IO.SpellTarget.Group)
{
// todo: implement packet handling for group target spells
builder = builder
.AddShort((short)spellId)
.AddThree(DateTime.Now.ToEOTimeStamp());
Expand Down
11 changes: 9 additions & 2 deletions EOLib/Domain/Chat/ChatActions.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using AutomaticTypeMapper;
using EOLib.Domain.Character;
using EOLib.Domain.Party;
using EOLib.Net;
using EOLib.Net.Builders;
using EOLib.Net.Communication;
Expand All @@ -15,13 +16,15 @@ public enum ChatResult
HideSpeechBubble,
Command,
AdminAnnounce,
HideAll,
}

[AutoMappedType]
public class ChatActions : IChatActions
{
private readonly IChatRepository _chatRepository;
private readonly ICharacterProvider _characterProvider;
private readonly IPartyDataProvider _partyDataProvider;
private readonly IChatTypeCalculator _chatTypeCalculator;
private readonly IChatPacketBuilder _chatPacketBuilder;
private readonly IPacketSendService _packetSendService;
Expand All @@ -30,6 +33,7 @@ public class ChatActions : IChatActions

public ChatActions(IChatRepository chatRepository,
ICharacterProvider characterProvider,
IPartyDataProvider partyDataProvider,
IChatTypeCalculator chatTypeCalculator,
IChatPacketBuilder chatPacketBuilder,
IPacketSendService packetSendService,
Expand All @@ -38,6 +42,7 @@ public ChatActions(IChatRepository chatRepository,
{
_chatRepository = chatRepository;
_characterProvider = characterProvider;
_partyDataProvider = partyDataProvider;
_chatTypeCalculator = chatTypeCalculator;
_chatPacketBuilder = chatPacketBuilder;
_packetSendService = packetSendService;
Expand All @@ -47,8 +52,6 @@ public ChatActions(IChatRepository chatRepository,

public (ChatResult, string) SendChatToServer(string chat, string targetCharacter)
{
// todo: if not in a group, don't do group chat

var chatType = _chatTypeCalculator.CalculateChatType(chat);

if (chatType == ChatType.Command)
Expand All @@ -66,6 +69,10 @@ public ChatActions(IChatRepository chatRepository,
else if (string.IsNullOrEmpty(_chatRepository.PMTarget2))
_chatRepository.PMTarget2 = targetCharacter;
}
else if (chatType == ChatType.Party && !_partyDataProvider.Members.Any())
{
return (ChatResult.HideAll, String.Empty);
}

chat = _chatProcessor.RemoveFirstCharacterIfNeeded(chat, chatType, targetCharacter);
var (ok, filtered) = _chatProcessor.FilterCurses(chat);
Expand Down
8 changes: 6 additions & 2 deletions EOLib/Domain/Chat/ChatLoggerProvider.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using AutomaticTypeMapper;
using EOLib.Config;
using EOLib.Logger;
using System;

Expand All @@ -14,9 +15,12 @@ public class ChatLoggerProvider : IChatLoggerProvider
{
public ILogger ChatLogger { get; }

public ChatLoggerProvider(ILoggerFactory loggerFactory)
public ChatLoggerProvider(IConfigurationProvider configurationProvider, ILoggerFactory loggerFactory)
{
ChatLogger = loggerFactory.CreateLogger<FileLogger>(Constants.ChatLogFile);
if (configurationProvider.LogChatToFile)
ChatLogger = loggerFactory.CreateLogger<FileLogger>(Constants.ChatLogFile);
else
ChatLogger = loggerFactory.CreateLogger<NullLogger>();
}

public void Dispose()
Expand Down
6 changes: 6 additions & 0 deletions EOLib/Domain/Notifiers/IOtherCharacterAnimationNotifier.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using AutomaticTypeMapper;
using EOLib.Domain.Spells;
using System.Collections.Generic;

namespace EOLib.Domain.Notifiers
{
Expand All @@ -13,6 +15,8 @@ public interface IOtherCharacterAnimationNotifier
void NotifySelfSpellCast(short playerId, short spellId, int spellHp, byte percentHealth);

void NotifyTargetOtherSpellCast(short sourcePlayerID, short targetPlayerID, short spellId, int recoveredHP, byte targetPercentHealth);

void NotifyGroupSpellCast(short playerId, short spellId, short spellHp, List<GroupSpellTarget> spellTargets);
}

[AutoMappedType]
Expand All @@ -27,5 +31,7 @@ public void NotifyStartSpellCast(short playerId, short spellId) { }
public void NotifySelfSpellCast(short playerId, short spellId, int spellHp, byte percentHealth) { }

public void NotifyTargetOtherSpellCast(short sourcePlayerID, short targetPlayerID, short spellId, int recoveredHP, byte targetPercentHealth) { }

public void NotifyGroupSpellCast(short playerId, short spellId, short spellHp, List<GroupSpellTarget> spellTargets) { }
}
}
28 changes: 28 additions & 0 deletions EOLib/Domain/Notifiers/IPartyEventNotifier.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using AutomaticTypeMapper;
using EOLib.Domain.Party;

namespace EOLib.Domain.Notifiers
{
public interface IPartyEventNotifier
{
void NotifyPartyRequest(PartyRequestType type, short playerId, string name);

void NotifyPartyJoined();

void NotifyPartyMemberAdd(string name);

void NotifyPartyMemberRemove(string name);
}

[AutoMappedType]
public class NoOpPartyEventNotifier : IPartyEventNotifier
{
public void NotifyPartyRequest(PartyRequestType type, short playerId, string name) { }

public void NotifyPartyJoined() { }

public void NotifyPartyMemberAdd(string name) { }

public void NotifyPartyMemberRemove(string name) { }
}
}
65 changes: 65 additions & 0 deletions EOLib/Domain/Party/PartyActions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using AutomaticTypeMapper;
using EOLib.Net;
using EOLib.Net.Communication;

namespace EOLib.Domain.Party
{
[AutoMappedType]
public class PartyActions : IPartyActions
{
private readonly IPacketSendService _packetSendService;

public PartyActions(IPacketSendService packetSendService)
{
_packetSendService = packetSendService;
}

public void RequestParty(PartyRequestType type, short targetCharacterId)
{
var packet = new PacketBuilder(PacketFamily.Party, PacketAction.Request)
.AddChar((byte)type)
.AddShort(targetCharacterId)
.Build();

_packetSendService.SendPacket(packet);
}

public void AcceptParty(PartyRequestType type, short targetCharacterId)
{
var packet = new PacketBuilder(PacketFamily.Party, PacketAction.Accept)
.AddChar((byte)type)
.AddShort(targetCharacterId)
.Build();

_packetSendService.SendPacket(packet);
}

public void ListParty()
{
var packet = new PacketBuilder(PacketFamily.Party, PacketAction.Take)
.Build();

_packetSendService.SendPacket(packet);
}

public void RemovePartyMember(short targetCharacterId)
{
var packet = new PacketBuilder(PacketFamily.Party, PacketAction.Remove)
.AddShort(targetCharacterId)
.Build();

_packetSendService.SendPacket(packet);
}
}

public interface IPartyActions
{
void RequestParty(PartyRequestType type, short targetCharacterId);

void AcceptParty(PartyRequestType type, short targetCharacterId);

void ListParty();

void RemovePartyMember(short targetCharacterId);
}
}
18 changes: 18 additions & 0 deletions EOLib/Domain/Party/PartyMember.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Amadevus.RecordGenerator;

namespace EOLib.Domain.Party
{
[Record(Features.ObjectEquals | Features.Withers | Features.Builder | Features.Constructor | Features.ToString)]
public sealed partial class PartyMember
{
public short CharacterID { get; }

public bool IsLeader { get; }

public byte Level { get; }

public byte PercentHealth { get; }

public string Name { get; }
}
}
28 changes: 28 additions & 0 deletions EOLib/Domain/Party/PartyRepository.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using AutomaticTypeMapper;
using System.Collections.Generic;

namespace EOLib.Domain.Party
{
public interface IPartyDataRepository
{
List<PartyMember> Members { get; }
}

public interface IPartyDataProvider
{
IReadOnlyList<PartyMember> Members { get; }
}

[AutoMappedType(IsSingleton = true)]
public class PartyDataRepository : IPartyDataRepository, IPartyDataProvider
{
public List<PartyMember> Members { get; set; }

IReadOnlyList<PartyMember> IPartyDataProvider.Members => Members;

public PartyDataRepository()
{
Members = new List<PartyMember>();
}
}
}
8 changes: 8 additions & 0 deletions EOLib/Domain/Party/PartyRequestType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace EOLib.Domain.Party
{
public enum PartyRequestType
{
Join,
Invite
}
}
14 changes: 14 additions & 0 deletions EOLib/Domain/Spells/GroupSpellTarget.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Amadevus.RecordGenerator;

namespace EOLib.Domain.Spells
{
[Record]
public sealed partial class GroupSpellTarget
{
public short TargetId { get; }

public byte PercentHealth { get; }

public short TargetHp { get; }
}
}
2 changes: 0 additions & 2 deletions EOLib/Net/API/PacketAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ public PacketAPI(EOClient client)
m_client = client;

//each of these sets up members of the partial PacketAPI class relevant to a particular packet family
_createPartyMembers();
_createSpellMembers();
_createTradeMembers();
}

Expand Down
Loading

0 comments on commit 434d599

Please sign in to comment.