baseline: OpenMU upstream b5a0961 (fresh source)

This commit is contained in:
Acentech Dev
2026-07-14 19:00:35 +03:00
parent 450402e47d
commit 36fc125d5c
11968 changed files with 748705 additions and 0 deletions

View File

@@ -0,0 +1,111 @@
// <copyright file="AssignPlayersToGuildPlugIn.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameServer.RemoteView.Guild;
using System.Runtime.InteropServices;
using MUnique.OpenMU.GameLogic;
using MUnique.OpenMU.GameLogic.Views;
using MUnique.OpenMU.GameLogic.Views.Guild;
using MUnique.OpenMU.Network;
using MUnique.OpenMU.Network.Packets.ServerToClient;
using MUnique.OpenMU.Network.PlugIns;
using MUnique.OpenMU.PlugIns;
/// <summary>
/// The default implementation of the <see cref="IAssignPlayersToGuildPlugIn"/> which is forwarding everything to the game client with specific data packets.
/// </summary>
[PlugIn]
[Display(Name = nameof(PlugInResources.AssignPlayersToGuildPlugIn_Name), Description = nameof(PlugInResources.AssignPlayersToGuildPlugIn_Description), ResourceType = typeof(PlugInResources))]
[Guid("f42f571e-0cd1-4c22-ba53-8344848ba998")]
[MinimumClient(0, 90, ClientLanguage.Invariant)]
public class AssignPlayersToGuildPlugIn : IAssignPlayersToGuildPlugIn
{
private readonly RemotePlayer _player;
/// <summary>
/// Initializes a new instance of the <see cref="AssignPlayersToGuildPlugIn"/> class.
/// </summary>
/// <param name="player">The player.</param>
public AssignPlayersToGuildPlugIn(RemotePlayer player) => this._player = player;
/// <inheritdoc />
public async ValueTask AssignPlayersToGuildAsync(ICollection<Player> guildPlayers, bool appearsNew)
{
var connection = this._player.Connection;
if (connection is null)
{
return;
}
// C2 00 11
// 65
// 01
// 34 4B 00 00 80 00 00
// A4 F2 00 00 00
int Write()
{
var size = AssignCharacterToGuildRef.GetRequiredSize(guildPlayers.Count);
var span = connection.Output.GetSpan(size)[..size];
var packet = new AssignCharacterToGuildRef(span)
{
PlayerCount = (byte)guildPlayers.Count,
};
int i = 0;
foreach (var guildPlayer in guildPlayers)
{
this.SetGuildPlayerBlock(packet[i], guildPlayer, appearsNew);
i++;
}
return size;
}
await connection.SendAsync(Write).ConfigureAwait(false);
}
/// <inheritdoc />
public async ValueTask AssignPlayerToGuildAsync(Player guildPlayer, bool appearsNew)
{
var connection = this._player.Connection;
if (connection is null)
{
return;
}
// C2 00 11
// 65
// 01
// 34 4B 00 00 80 00 00
// A4 F2 00 00 00
int Write()
{
var size = AssignCharacterToGuildRef.GetRequiredSize(1);
var span = connection.Output.GetSpan(size)[..size];
var packet = new AssignCharacterToGuildRef(span)
{
PlayerCount = 1,
};
this.SetGuildPlayerBlock(packet[0], guildPlayer, appearsNew);
return size;
}
await connection.SendAsync(Write).ConfigureAwait(false);
}
private void SetGuildPlayerBlock(AssignCharacterToGuildRef.GuildMemberRelationRef playerBlock, Player guildPlayer, bool appearsNew)
{
if (guildPlayer.GuildStatus is null)
{
return;
}
playerBlock.GuildId = guildPlayer.GuildStatus.GuildId;
playerBlock.Role = guildPlayer.GuildStatus.Position.Convert();
playerBlock.PlayerId = guildPlayer.GetId(this._player);
playerBlock.IsPlayerAppearingNew = appearsNew;
}
}

View File

@@ -0,0 +1,166 @@
// <copyright file="AssignPlayersToGuildPlugIn075.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameServer.RemoteView.Guild;
using System.Runtime.InteropServices;
using MUnique.OpenMU.GameLogic;
using MUnique.OpenMU.GameLogic.Views;
using MUnique.OpenMU.GameLogic.Views.Guild;
using MUnique.OpenMU.Network;
using MUnique.OpenMU.Network.Packets.ServerToClient;
using MUnique.OpenMU.Network.PlugIns;
using MUnique.OpenMU.PlugIns;
/// <summary>
/// The default implementation of the <see cref="IAssignPlayersToGuildPlugIn"/> which is forwarding everything to the game client with specific data packets.
/// </summary>
[PlugIn]
[Display(Name = nameof(PlugInResources.AssignPlayersToGuildPlugIn075_Name), Description = nameof(PlugInResources.AssignPlayersToGuildPlugIn075_Description), ResourceType = typeof(PlugInResources))]
[Guid("ABFA2CBD-1AB0-4F56-97A7-FCF458865ACF")]
[MaximumClient(0, 89, ClientLanguage.Invariant)]
public class AssignPlayersToGuildPlugIn075 : BaseGuildInfoPlugIn<AssignPlayersToGuildPlugIn075>, IAssignPlayersToGuildPlugIn
{
private readonly RemotePlayer _player;
private readonly HashSet<uint> _transmittedGuilds = new();
/// <summary>
/// Initializes a new instance of the <see cref="AssignPlayersToGuildPlugIn075"/> class.
/// </summary>
/// <param name="player">The player.</param>
public AssignPlayersToGuildPlugIn075(RemotePlayer player)
: base(player)
{
this._player = player;
}
/// <inheritdoc />
public async ValueTask AssignPlayersToGuildAsync(ICollection<Player> guildPlayers, bool appearsNew)
{
var connection = this._player.Connection;
if (connection is null)
{
return;
}
foreach (var guildPlayer in guildPlayers)
{
await this.SendGuildInfoIfRequiredAsync(guildPlayer).ConfigureAwait(false);
}
int Write()
{
var size = AssignCharacterToGuild075Ref.GetRequiredSize(guildPlayers.Count);
var span = connection.Output.GetSpan(size)[..size];
var packet = new AssignCharacterToGuild075Ref(span)
{
PlayerCount = (byte)guildPlayers.Count,
};
int i = 0;
foreach (var guildPlayer in guildPlayers)
{
this.SetGuildPlayerBlock(packet[i], guildPlayer);
i++;
}
return size;
}
await connection.SendAsync(Write).ConfigureAwait(false);
}
/// <inheritdoc />
public async ValueTask AssignPlayerToGuildAsync(Player guildPlayer, bool appearsNew)
{
var connection = this._player.Connection;
if (connection is null)
{
return;
}
await this.SendGuildInfoIfRequiredAsync(guildPlayer).ConfigureAwait(false);
// C2 00 11
// 65
// 01
// 34 4B 00 00 80 00 00
// A4 F2 00 00 00
int Write()
{
var size = AssignCharacterToGuild075Ref.GetRequiredSize(1);
var span = connection.Output.GetSpan(size)[..size];
var packet = new AssignCharacterToGuild075Ref(span)
{
PlayerCount = 1,
};
this.SetGuildPlayerBlock(packet[0], guildPlayer);
return size;
}
await connection.SendAsync(Write).ConfigureAwait(false);
}
/// <inheritdoc />
protected override Memory<byte> Serialize(Interfaces.Guild guild, uint guildId)
{
var array = new byte[GuildInformations075.GetRequiredSize(1)];
var result = new GuildInformations075(array) { GuildCount = 1 };
var guildInfo = result[0];
guildInfo.GuildId = (ushort)guildId;
guildInfo.GuildName = guild.Name ?? string.Empty;
guild.Logo.CopyTo(guildInfo.Logo);
return array.AsMemory();
}
private async ValueTask SendGuildInfoIfRequiredAsync(Player guildPlayer)
{
if (guildPlayer.GuildStatus is not { } guildStatus)
{
return;
}
if (this._transmittedGuilds.Contains(guildStatus.GuildId))
{
return;
}
var data = await this.GetGuildDataAsync(guildStatus.GuildId).ConfigureAwait(false);
if (data.Length == 0)
{
return;
}
var connection = this.Player.Connection;
if (connection is null)
{
return;
}
this._transmittedGuilds.Add(guildStatus.GuildId);
// guildInfo is the cached, serialized result of the GuildInformation-Class.
int Write()
{
var target = connection.Output.GetSpan(data.Length);
data.Span.CopyTo(target);
return data.Length;
}
await connection.SendAsync(Write).ConfigureAwait(false);
}
private void SetGuildPlayerBlock(AssignCharacterToGuild075Ref.GuildMemberRelationRef playerBlock, Player guildPlayer)
{
if (guildPlayer.GuildStatus is null)
{
return;
}
playerBlock.GuildId = (ushort)guildPlayer.GuildStatus.GuildId;
playerBlock.PlayerId = guildPlayer.GetId(this._player);
}
}

View File

@@ -0,0 +1,92 @@
// <copyright file="BaseGuildInfoPlugIn.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameServer.RemoteView.Guild;
using System.Collections.Concurrent;
using MUnique.OpenMU.GameLogic;
using MUnique.OpenMU.GameLogic.Views.Guild;
using MUnique.OpenMU.Interfaces;
/// <summary>
/// Abstract base class for a <see cref="IShowGuildInfoPlugIn" /> which allows to cache serialized guild infos.
/// </summary>
/// <typeparam name="T">The type of the actual <see cref="IShowGuildInfoPlugIn"/>. Required, so there is one cache per type.</typeparam>
// ReSharper disable once UnusedTypeParameter we just use it to get type specific static fields.
public abstract class BaseGuildInfoPlugIn<T>
{
/// <summary>
/// The cache for already serialized guilds. This data doesn't change, but is requested often.
/// </summary>
// ReSharper disable once StaticMemberInGenericType That's what we want
private static readonly ConcurrentDictionary<uint, Memory<byte>> Cache = new();
// ReSharper disable once StaticMemberInGenericType That's what we want
private static readonly HashSet<IGameServerContext> AppendedGuildDeletedSenders = new();
/// <summary>
/// Initializes a new instance of the <see cref="BaseGuildInfoPlugIn{T}"/> class.
/// </summary>
/// <param name="player">The player.</param>
protected BaseGuildInfoPlugIn(RemotePlayer player)
{
this.Player = player;
lock (AppendedGuildDeletedSenders)
{
if (AppendedGuildDeletedSenders.Add(player.GameServerContext))
{
// to make sure we just add one event handler
this.Player.GameServerContext.GuildDeleted += OnGuildChanged;
this.Player.GameServerContext.GuildChanged += OnGuildChanged;
}
}
}
/// <summary>
/// Gets the player.
/// </summary>
/// <value>
/// The player.
/// </value>
protected RemotePlayer Player { get; }
/// <summary>
/// Serializes the specified guild.
/// </summary>
/// <param name="guild">The guild.</param>
/// <param name="guildId">The guild identifier.</param>
/// <returns>The serialized guild data packet.</returns>
protected abstract Memory<byte> Serialize(Guild guild, uint guildId);
/// <summary>
/// Returns the Guild Info Data of a Guild. It will either
/// take the data out of the Cache, or get it from the database and serializes it.
/// </summary>
/// <param name="guildId">The id of the guild.</param>
/// <returns>
/// The data of the guild.
/// </returns>
protected async ValueTask<Memory<byte>> GetGuildDataAsync(uint guildId)
{
if (Cache.TryGetValue(guildId, out var guildInfo))
{
return guildInfo;
}
var guild = await this.Player.GameServerContext.GuildServer.GetGuildAsync(guildId).ConfigureAwait(false);
if (guild is null)
{
return Memory<byte>.Empty;
}
var data = this.Serialize(guild, guildId);
Cache.TryAdd(guildId, data);
return data;
}
private static void OnGuildChanged(object? sender, GuildEventArgs args)
{
Cache.TryRemove(args.GuildId, out _);
}
}

View File

@@ -0,0 +1,217 @@
// <copyright file="EnumExtensions.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameServer.RemoteView.Guild;
using MUnique.OpenMU.GameLogic.Views.Guild;
using MUnique.OpenMU.Interfaces;
using MUnique.OpenMU.Network.Packets.ServerToClient;
using static MUnique.OpenMU.Network.Packets.ServerToClient.GuildJoinResponse;
/// <summary>
/// Extension methods for enum types.
/// </summary>
public static class EnumExtensions
{
/// <summary>
/// Gets the view value.
/// </summary>
/// <param name="playerPosition">The player position.</param>
/// <returns>The value which is used in the message for the corresponding enum value.</returns>
public static GuildMemberRole Convert(this GuildPosition? playerPosition)
{
if (playerPosition.HasValue)
{
return playerPosition.Value.Convert();
}
return GuildMemberRole.Undefined;
}
/// <summary>
/// Gets the view value.
/// </summary>
/// <param name="playerPosition">The player position.</param>
/// <returns>The value which is used in the message for the corresponding enum value.</returns>
public static GuildMemberRole Convert(this GuildPosition playerPosition)
{
return playerPosition switch
{
GuildPosition.GuildMaster => GuildMemberRole.GuildMaster,
GuildPosition.AssistantMaster => GuildMemberRole.AssistantMaster,
GuildPosition.NormalMember => GuildMemberRole.NormalMember,
GuildPosition.BattleMaster => GuildMemberRole.BattleMaster,
_ => GuildMemberRole.Undefined,
};
}
/// <summary>
/// Converts the <see cref="GuildRequestAnswerResult"/> into a <see cref="GuildJoinRequestResult"/>.
/// </summary>
/// <param name="result">The <see cref="GuildRequestAnswerResult"/> which should be converted.</param>
/// <returns>The converted value.</returns>
public static GuildJoinRequestResult Convert(this GuildRequestAnswerResult result)
{
return result switch
{
GuildRequestAnswerResult.Refused => GuildJoinRequestResult.Refused,
GuildRequestAnswerResult.Accepted => GuildJoinRequestResult.Accepted,
GuildRequestAnswerResult.GuildFull => GuildJoinRequestResult.GuildFull,
GuildRequestAnswerResult.Disconnected => GuildJoinRequestResult.Disconnected,
GuildRequestAnswerResult.NotTheGuildMaster => GuildJoinRequestResult.NotTheGuildMaster,
GuildRequestAnswerResult.AlreadyHaveGuild => GuildJoinRequestResult.AlreadyHaveGuild,
GuildRequestAnswerResult.GuildMasterOrRequesterIsBusy => GuildJoinRequestResult.GuildMasterOrRequesterIsBusy,
GuildRequestAnswerResult.MinimumLevel6 => GuildJoinRequestResult.MinimumLevel6,
_ => throw new NotImplementedException($"The case {result} is not implemented."),
};
}
/// <summary>
/// Converts a <see cref="GuildKickSuccess"/> into a <see cref="GuildKickResponse.GuildKickSuccess"/>.
/// </summary>
/// <param name="success">The <see cref="GuildKickSuccess"/> which should be converted.</param>
/// <returns>The converted <see cref="GuildKickResponse.GuildKickSuccess"/>.</returns>
public static GuildKickResponse.GuildKickSuccess Convert(this GuildKickSuccess success)
{
return success switch
{
GuildKickSuccess.Failed => GuildKickResponse.GuildKickSuccess.Failed,
GuildKickSuccess.FailedBecausePlayerIsNotGuildMaster => GuildKickResponse.GuildKickSuccess.KickFailedBecausePlayerIsNotGuildMaster,
GuildKickSuccess.KickSucceeded => GuildKickResponse.GuildKickSuccess.KickSucceeded,
GuildKickSuccess.GuildDisband => GuildKickResponse.GuildKickSuccess.GuildDisband,
_ => throw new NotImplementedException($"The case {success} is not implemented."),
};
}
/// <summary>
/// Converts a <see cref="GuildCreateErrorDetail"/> into a <see cref="GuildCreationResult.GuildCreationErrorType"/>.
/// </summary>
/// <param name="errorDetail">The <see cref="GuildCreateErrorDetail"/> which should be converted.</param>
/// <returns>The converted <see cref="GuildCreationResult.GuildCreationErrorType"/>.</returns>
public static GuildCreationResult.GuildCreationErrorType Convert(this GuildCreateErrorDetail errorDetail)
{
return errorDetail switch
{
GuildCreateErrorDetail.None => GuildCreationResult.GuildCreationErrorType.None,
GuildCreateErrorDetail.GuildAlreadyExist => GuildCreationResult.GuildCreationErrorType.GuildNameAlreadyTaken,
_ => throw new NotImplementedException($"The case {errorDetail} is not implemented."),
};
}
/// <summary>
/// Converts a <see cref="GameLogic.GuildWar.GuildWarType"/> into a <see cref="Network.Packets.ServerToClient.GuildWarType"/>.
/// </summary>
/// <param name="guildWarType">The <see cref="GameLogic.GuildWar.GuildWarType"/> which should be converted.</param>
/// <returns>The converted <see cref="Network.Packets.ServerToClient.GuildWarType"/>.</returns>
public static Network.Packets.ServerToClient.GuildWarType Convert(this GameLogic.GuildWar.GuildWarType guildWarType)
{
return guildWarType switch
{
GameLogic.GuildWar.GuildWarType.Normal => Network.Packets.ServerToClient.GuildWarType.Normal,
GameLogic.GuildWar.GuildWarType.Soccer => Network.Packets.ServerToClient.GuildWarType.Soccer,
_ => throw new NotImplementedException($"The case {guildWarType} is not implemented."),
};
}
/// <summary>
/// Converts a <see cref="GameLogic.Views.Guild.GuildWarResult"/> into a <see cref="GuildWarEnded.GuildWarResult"/>.
/// </summary>
/// <param name="guildWarResult">The <see cref="GameLogic.Views.Guild.GuildWarResult"/> which should be converted.</param>
/// <returns>The converted <see cref="GuildWarEnded.GuildWarResult"/>.</returns>
public static GuildWarEnded.GuildWarResult Convert(this GuildWarResult guildWarResult)
{
return guildWarResult switch
{
GuildWarResult.Lost => GuildWarEnded.GuildWarResult.Lost,
GuildWarResult.Won => GuildWarEnded.GuildWarResult.Won,
GuildWarResult.CancelledWar => GuildWarEnded.GuildWarResult.CancelledWar,
GuildWarResult.OtherGuildMasterCancelledWar => GuildWarEnded.GuildWarResult.OtherGuildMasterCancelledWar,
_ => throw new NotImplementedException($"The case {guildWarResult} is not implemented."),
};
}
/// <summary>
/// Converts a <see cref="GameLogic.Views.Guild.GuildWarRequestResult"/> into a <see cref="Network.Packets.ServerToClient.GuildWarRequestResult.RequestResult"/>.
/// </summary>
/// <param name="result">The <see cref="GameLogic.Views.Guild.GuildWarRequestResult"/> which should be converted.</param>
/// <returns>The converted <see cref="Network.Packets.ServerToClient.GuildWarRequestResult.RequestResult"/>.</returns>
public static Network.Packets.ServerToClient.GuildWarRequestResult.RequestResult Convert(this GameLogic.Views.Guild.GuildWarRequestResult result)
{
return result switch
{
GameLogic.Views.Guild.GuildWarRequestResult.AlreadyInWar => Network.Packets.ServerToClient.GuildWarRequestResult.RequestResult.AlreadyInWar,
GameLogic.Views.Guild.GuildWarRequestResult.Failed => Network.Packets.ServerToClient.GuildWarRequestResult.RequestResult.Failed,
GameLogic.Views.Guild.GuildWarRequestResult.GuildMasterOffline => Network.Packets.ServerToClient.GuildWarRequestResult.RequestResult.GuildMasterOffline,
GameLogic.Views.Guild.GuildWarRequestResult.GuildNotFound => Network.Packets.ServerToClient.GuildWarRequestResult.RequestResult.GuildNotFound,
GameLogic.Views.Guild.GuildWarRequestResult.NotInGuild => Network.Packets.ServerToClient.GuildWarRequestResult.RequestResult.NotInGuild,
GameLogic.Views.Guild.GuildWarRequestResult.NotTheGuildMaster => Network.Packets.ServerToClient.GuildWarRequestResult.RequestResult.NotTheGuildMaster,
GameLogic.Views.Guild.GuildWarRequestResult.RequestSentToGuildMaster => Network.Packets.ServerToClient.GuildWarRequestResult.RequestResult.RequestSentToGuildMaster,
_ => throw new NotImplementedException($"The case {result} is not implemented."),
};
}
/// <summary>
/// Converts the specified relationship type.
/// </summary>
/// <param name="relationshipType">Type of the relationship.</param>
/// <returns>The converted <see cref="Network.Packets.ServerToClient.GuildRelationshipType"/>.</returns>
public static Network.Packets.ServerToClient.GuildRelationshipType Convert(this GameLogic.Views.Guild.GuildRelationshipType relationshipType)
{
return relationshipType switch
{
GameLogic.Views.Guild.GuildRelationshipType.Undefined => Network.Packets.ServerToClient.GuildRelationshipType.Undefined,
GameLogic.Views.Guild.GuildRelationshipType.Alliance => Network.Packets.ServerToClient.GuildRelationshipType.Alliance,
GameLogic.Views.Guild.GuildRelationshipType.Hostility => Network.Packets.ServerToClient.GuildRelationshipType.Hostility,
_ => throw new NotImplementedException($"The case {relationshipType} is not implemented."),
};
}
/// <summary>
/// Converts the specified request type.
/// </summary>
/// <param name="requestType">Type of the request.</param>
/// <returns>The converted <see cref="Network.Packets.ServerToClient.GuildRelationshipRequestType"/>.</returns>
public static Network.Packets.ServerToClient.GuildRelationshipRequestType Convert(this GameLogic.Views.Guild.GuildRelationshipRequestType requestType)
{
return requestType switch
{
GameLogic.Views.Guild.GuildRelationshipRequestType.Undefined => Network.Packets.ServerToClient.GuildRelationshipRequestType.Undefined,
GameLogic.Views.Guild.GuildRelationshipRequestType.Join => Network.Packets.ServerToClient.GuildRelationshipRequestType.Join,
GameLogic.Views.Guild.GuildRelationshipRequestType.Leave => Network.Packets.ServerToClient.GuildRelationshipRequestType.Leave,
_ => throw new NotImplementedException($"The case {requestType} is not implemented."),
};
}
/// <summary>
/// Converts the specified result type.
/// </summary>
/// <param name="result">The <see cref="GameLogic.Views.Guild.GuildRelationshipChangeResultType"/> which should be converted.</param>
/// <returns>The converted <see cref="Network.Packets.ServerToClient.GuildRelationshipChangeResult.GuildRelationshipChangeResultType"/>.</returns>
public static Network.Packets.ServerToClient.GuildRelationshipChangeResult.GuildRelationshipChangeResultType Convert(this GameLogic.Views.Guild.GuildRelationshipChangeResultType result)
{
return result switch
{
GameLogic.Views.Guild.GuildRelationshipChangeResultType.Failed => Network.Packets.ServerToClient.GuildRelationshipChangeResult.GuildRelationshipChangeResultType.Failed,
GameLogic.Views.Guild.GuildRelationshipChangeResultType.Success => Network.Packets.ServerToClient.GuildRelationshipChangeResult.GuildRelationshipChangeResultType.Success,
GameLogic.Views.Guild.GuildRelationshipChangeResultType.GuildNotFound => Network.Packets.ServerToClient.GuildRelationshipChangeResult.GuildRelationshipChangeResultType.GuildNotFound,
GameLogic.Views.Guild.GuildRelationshipChangeResultType.NoAuthorization => Network.Packets.ServerToClient.GuildRelationshipChangeResult.GuildRelationshipChangeResultType.NoAuthorization,
GameLogic.Views.Guild.GuildRelationshipChangeResultType.AlreadyInAlliance => Network.Packets.ServerToClient.GuildRelationshipChangeResult.GuildRelationshipChangeResultType.AlreadyInAlliance,
GameLogic.Views.Guild.GuildRelationshipChangeResultType.FailedDuringCastleSiege => Network.Packets.ServerToClient.GuildRelationshipChangeResult.GuildRelationshipChangeResultType.FailedDuringCastleSiege,
GameLogic.Views.Guild.GuildRelationshipChangeResultType.AlreadyInHostility => Network.Packets.ServerToClient.GuildRelationshipChangeResult.GuildRelationshipChangeResultType.AlreadyInHostility,
GameLogic.Views.Guild.GuildRelationshipChangeResultType.GuildAllianceExists => Network.Packets.ServerToClient.GuildRelationshipChangeResult.GuildRelationshipChangeResultType.GuildAllianceExists,
GameLogic.Views.Guild.GuildRelationshipChangeResultType.HostileGuildExists => Network.Packets.ServerToClient.GuildRelationshipChangeResult.GuildRelationshipChangeResultType.HostileGuildExists,
GameLogic.Views.Guild.GuildRelationshipChangeResultType.GuildAllianceDoesNotExist => Network.Packets.ServerToClient.GuildRelationshipChangeResult.GuildRelationshipChangeResultType.GuildAllianceDoesNotExist,
GameLogic.Views.Guild.GuildRelationshipChangeResultType.HostileGuildDoesNotExist => Network.Packets.ServerToClient.GuildRelationshipChangeResult.GuildRelationshipChangeResultType.HostileGuildDoesNotExist,
GameLogic.Views.Guild.GuildRelationshipChangeResultType.NotMasterOfGuildAlliance => Network.Packets.ServerToClient.GuildRelationshipChangeResult.GuildRelationshipChangeResultType.NotMasterOfGuildAlliance,
GameLogic.Views.Guild.GuildRelationshipChangeResultType.NotGuildRival => Network.Packets.ServerToClient.GuildRelationshipChangeResult.GuildRelationshipChangeResultType.NotGuildRival,
GameLogic.Views.Guild.GuildRelationshipChangeResultType.IncompleteRequirementsToCreateAlliance => Network.Packets.ServerToClient.GuildRelationshipChangeResult.GuildRelationshipChangeResultType.IncompleteRequirementsToCreateAlliance,
GameLogic.Views.Guild.GuildRelationshipChangeResultType.MaximumNumberOfGuildsInAllianceReached => Network.Packets.ServerToClient.GuildRelationshipChangeResult.GuildRelationshipChangeResultType.MaximumNumberOfGuildsInAllianceReached,
GameLogic.Views.Guild.GuildRelationshipChangeResultType.RequestCancelled => Network.Packets.ServerToClient.GuildRelationshipChangeResult.GuildRelationshipChangeResultType.RequestCancelled,
GameLogic.Views.Guild.GuildRelationshipChangeResultType.AllianceMasterNotInGens => Network.Packets.ServerToClient.GuildRelationshipChangeResult.GuildRelationshipChangeResultType.AllianceMasterNotInGens,
GameLogic.Views.Guild.GuildRelationshipChangeResultType.GuildMasterNotInGens => Network.Packets.ServerToClient.GuildRelationshipChangeResult.GuildRelationshipChangeResultType.GuildMasterNotInGens,
GameLogic.Views.Guild.GuildRelationshipChangeResultType.DifferentGens => Network.Packets.ServerToClient.GuildRelationshipChangeResult.GuildRelationshipChangeResultType.DifferentGens,
_ => throw new NotImplementedException($"The case {result} is not implemented."),
};
}
}

View File

@@ -0,0 +1,33 @@
// <copyright file="GuildJoinResponsePlugIn.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameServer.RemoteView.Guild;
using System.Runtime.InteropServices;
using MUnique.OpenMU.GameLogic.Views.Guild;
using MUnique.OpenMU.Network.Packets.ServerToClient;
using MUnique.OpenMU.PlugIns;
/// <summary>
/// The default implementation of the <see cref="IGuildJoinResponsePlugIn"/> which is forwarding everything to the game client with specific data packets.
/// </summary>
[PlugIn]
[Display(Name = nameof(PlugInResources.GuildJoinResponsePlugIn_Name), Description = nameof(PlugInResources.GuildJoinResponsePlugIn_Description), ResourceType = typeof(PlugInResources))]
[Guid("4a8bd97c-a544-4cac-b8cd-2e73945bcfdc")]
public class GuildJoinResponsePlugIn : IGuildJoinResponsePlugIn
{
private readonly RemotePlayer _player;
/// <summary>
/// Initializes a new instance of the <see cref="GuildJoinResponsePlugIn"/> class.
/// </summary>
/// <param name="player">The player.</param>
public GuildJoinResponsePlugIn(RemotePlayer player) => this._player = player;
/// <inheritdoc/>
public async ValueTask ShowGuildJoinResponseAsync(GuildRequestAnswerResult result)
{
await this._player.Connection.SendGuildJoinResponseAsync(result.Convert()).ConfigureAwait(false);
}
}

View File

@@ -0,0 +1,33 @@
// <copyright file="GuildKickResultPlugIn.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameServer.RemoteView.Guild;
using System.Runtime.InteropServices;
using MUnique.OpenMU.GameLogic.Views.Guild;
using MUnique.OpenMU.Network.Packets.ServerToClient;
using MUnique.OpenMU.PlugIns;
/// <summary>
/// The default implementation of the <see cref="IGuildKickResultPlugIn"/> which is forwarding everything to the game client with specific data packets.
/// </summary>
[PlugIn]
[Display(Name = nameof(PlugInResources.GuildKickResultPlugIn_Name), Description = nameof(PlugInResources.GuildKickResultPlugIn_Description), ResourceType = typeof(PlugInResources))]
[Guid("0e91e131-12c4-4add-9439-febb7d444083")]
public class GuildKickResultPlugIn : IGuildKickResultPlugIn
{
private readonly RemotePlayer _player;
/// <summary>
/// Initializes a new instance of the <see cref="GuildKickResultPlugIn"/> class.
/// </summary>
/// <param name="player">The player.</param>
public GuildKickResultPlugIn(RemotePlayer player) => this._player = player;
/// <inheritdoc/>
public async ValueTask GuildKickResultAsync(GuildKickSuccess successCode)
{
await this._player.Connection.SendGuildKickResponseAsync(successCode.Convert()).ConfigureAwait(false);
}
}

View File

@@ -0,0 +1,36 @@
// <copyright file="GuildWarScoreUpdatePlugIn.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameServer.RemoteView.Guild;
using System.Runtime.InteropServices;
using MUnique.OpenMU.GameLogic.Views.Guild;
using MUnique.OpenMU.Network.Packets.ServerToClient;
using MUnique.OpenMU.PlugIns;
/// <summary>
/// The default implementation of the <see cref="IGuildWarScoreUpdatePlugIn"/> which is forwarding everything to the game client with specific data packets.
/// </summary>
[PlugIn]
[Display(Name = nameof(PlugInResources.GuildWarScoreUpdatePlugIn_Name), Description = nameof(PlugInResources.GuildWarScoreUpdatePlugIn_Description), ResourceType = typeof(PlugInResources))]
[Guid("24E5E0C1-DAE7-4E34-810D-C622F8F9B70F")]
public class GuildWarScoreUpdatePlugIn : IGuildWarScoreUpdatePlugIn
{
private readonly RemotePlayer _player;
/// <summary>
/// Initializes a new instance of the <see cref="GuildWarScoreUpdatePlugIn"/> class.
/// </summary>
/// <param name="player">The player.</param>
public GuildWarScoreUpdatePlugIn(RemotePlayer player) => this._player = player;
/// <inheritdoc/>
public async ValueTask UpdateScoreAsync()
{
if (this._player.GuildWarContext is { } guildWarContext)
{
await this._player.Connection.SendGuildWarScoreUpdateAsync(guildWarContext.ThisScore, guildWarContext.EnemyScore).ConfigureAwait(false);
}
}
}

View File

@@ -0,0 +1,39 @@
// <copyright file="PlayerLeftGuildPlugIn.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameServer.RemoteView.Guild;
using System.Runtime.InteropServices;
using MUnique.OpenMU.GameLogic;
using MUnique.OpenMU.GameLogic.Views;
using MUnique.OpenMU.GameLogic.Views.Guild;
using MUnique.OpenMU.Interfaces;
using MUnique.OpenMU.Network.Packets.ServerToClient;
using MUnique.OpenMU.PlugIns;
/// <summary>
/// The default implementation of the <see cref="IPlayerLeftGuildPlugIn"/> which is forwarding everything to the game client with specific data packets.
/// </summary>
[PlugIn]
[Display(Name = nameof(PlugInResources.PlayerLeftGuildPlugIn_Name), Description = nameof(PlugInResources.PlayerLeftGuildPlugIn_Description), ResourceType = typeof(PlugInResources))]
[Guid("e37868e8-6fdf-41fb-aa7f-01e6f569f5c0")]
public class PlayerLeftGuildPlugIn : IPlayerLeftGuildPlugIn
{
private readonly RemotePlayer _player;
/// <summary>
/// Initializes a new instance of the <see cref="PlayerLeftGuildPlugIn"/> class.
/// </summary>
/// <param name="player">The player.</param>
public PlayerLeftGuildPlugIn(RemotePlayer player) => this._player = player;
/// <inheritdoc/>
public async ValueTask PlayerLeftGuildAsync(Player player)
{
await this._player.Connection.SendGuildMemberLeftGuildAsync(
player.GetId(this._player),
player.GuildStatus?.Position == GuildPosition.GuildMaster)
.ConfigureAwait(false);
}
}

View File

@@ -0,0 +1,64 @@
// <copyright file="ShowAllianceListPlugIn.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameServer.RemoteView.Guild;
using System.Runtime.InteropServices;
using MUnique.OpenMU.GameLogic.Views.Guild;
using MUnique.OpenMU.Interfaces;
using MUnique.OpenMU.Network;
using MUnique.OpenMU.Network.Packets.ServerToClient;
using MUnique.OpenMU.PlugIns;
/// <summary>
/// The default implementation of the <see cref="IShowAllianceListPlugIn"/> which is forwarding everything to the game client with specific data packets.
/// </summary>
[PlugIn]
[Display(Name = nameof(PlugInResources.ShowAllianceListPlugIn_Name), Description = nameof(PlugInResources.ShowAllianceListPlugIn_Description), ResourceType = typeof(PlugInResources))]
[Guid("A8B9C0D1-E2F3-4A4B-5C6D-7E8F9A0B1C2D")]
public class ShowAllianceListPlugIn : IShowAllianceListPlugIn
{
private readonly RemotePlayer _player;
/// <summary>
/// Initializes a new instance of the <see cref="ShowAllianceListPlugIn"/> class.
/// </summary>
/// <param name="player">The player.</param>
public ShowAllianceListPlugIn(RemotePlayer player) => this._player = player;
/// <inheritdoc/>
public async ValueTask ShowListAsync(IEnumerable<AllianceGuildEntry> guilds)
{
var connection = this._player.Connection;
if (connection is null)
{
return;
}
var guildList = guilds.ToList();
int guildCount = guildList.Count;
int Write()
{
var size = AllianceList.GetRequiredSize(guildCount);
var packet = new AllianceListRef(connection.Output.GetSpan(size)[..size])
{
GuildCount = (byte)guildCount,
Success = true,
};
for (int i = 0; i < guildCount; i++)
{
var entry = packet[i];
entry.GuildName = guildList[i].GuildName;
entry.MemberCount = (byte)guildList[i].MemberCount;
guildList[i].Logo.Span.CopyTo(entry.Logo);
}
return size;
}
await connection.SendAsync(Write).ConfigureAwait(false);
}
}

View File

@@ -0,0 +1,33 @@
// <copyright file="ShowGuildCreateResultPlugIn.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameServer.RemoteView.Guild;
using System.Runtime.InteropServices;
using MUnique.OpenMU.GameLogic.Views.Guild;
using MUnique.OpenMU.Network.Packets.ServerToClient;
using MUnique.OpenMU.PlugIns;
/// <summary>
/// The default implementation of the <see cref="IShowGuildCreateResultPlugIn"/> which is forwarding everything to the game client with specific data packets.
/// </summary>
[PlugIn]
[Display(Name = nameof(PlugInResources.ShowGuildCreateResultPlugIn_Name), Description = nameof(PlugInResources.ShowGuildCreateResultPlugIn_Description), ResourceType = typeof(PlugInResources))]
[Guid("ff6c5a06-4699-461b-9004-756269393c40")]
public class ShowGuildCreateResultPlugIn : IShowGuildCreateResultPlugIn
{
private readonly RemotePlayer _player;
/// <summary>
/// Initializes a new instance of the <see cref="ShowGuildCreateResultPlugIn"/> class.
/// </summary>
/// <param name="player">The player.</param>
public ShowGuildCreateResultPlugIn(RemotePlayer player) => this._player = player;
/// <inheritdoc/>
public async ValueTask ShowGuildCreateResultAsync(GuildCreateErrorDetail errorDetail)
{
await this._player.Connection.SendGuildCreationResultAsync(errorDetail == GuildCreateErrorDetail.None, errorDetail.Convert()).ConfigureAwait(false);
}
}

View File

@@ -0,0 +1,33 @@
// <copyright file="ShowGuildCreationDialogPlugIn.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameServer.RemoteView.Guild;
using System.Runtime.InteropServices;
using MUnique.OpenMU.GameLogic.Views.Guild;
using MUnique.OpenMU.Network.Packets.ServerToClient;
using MUnique.OpenMU.PlugIns;
/// <summary>
/// The default implementation of the <see cref="IShowGuildCreationDialogPlugIn"/> which is forwarding everything to the game client with specific data packets.
/// </summary>
[PlugIn]
[Display(Name = nameof(PlugInResources.ShowGuildCreationDialogPlugIn_Name), Description = nameof(PlugInResources.ShowGuildCreationDialogPlugIn_Description), ResourceType = typeof(PlugInResources))]
[Guid("ed6fbe5f-7a27-477d-b238-e6e77cf113d8")]
public class ShowGuildCreationDialogPlugIn : IShowGuildCreationDialogPlugIn
{
private readonly RemotePlayer _player;
/// <summary>
/// Initializes a new instance of the <see cref="ShowGuildCreationDialogPlugIn"/> class.
/// </summary>
/// <param name="player">The player.</param>
public ShowGuildCreationDialogPlugIn(RemotePlayer player) => this._player = player;
/// <inheritdoc/>
public async ValueTask ShowGuildCreationDialogAsync()
{
await this._player.Connection.SendShowGuildCreationDialogAsync().ConfigureAwait(false);
}
}

View File

@@ -0,0 +1,83 @@
// <copyright file="ShowGuildInfoPlugIn.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameServer.RemoteView.Guild;
using System.Runtime.InteropServices;
using MUnique.OpenMU.GameLogic.Views.Guild;
using MUnique.OpenMU.Interfaces;
using MUnique.OpenMU.Network;
using MUnique.OpenMU.Network.Packets.ServerToClient;
using MUnique.OpenMU.PlugIns;
/// <summary>
/// The default implementation of the <see cref="IShowGuildInfoPlugIn"/> which is forwarding everything to the game client with specific data packets.
/// </summary>
[PlugIn]
[Display(Name = nameof(PlugInResources.ShowGuildInfoPlugIn_Name), Description = nameof(PlugInResources.ShowGuildInfoPlugIn_Description), ResourceType = typeof(PlugInResources))]
[Guid("65f9d310-4adf-48b4-ace2-16779b254ecf")]
public class ShowGuildInfoPlugIn : BaseGuildInfoPlugIn<ShowGuildInfoPlugIn>, IShowGuildInfoPlugIn
{
/// <summary>
/// Initializes a new instance of the <see cref="ShowGuildInfoPlugIn"/> class.
/// </summary>
/// <param name="player">The player.</param>
public ShowGuildInfoPlugIn(RemotePlayer player)
: base(player)
{
}
/// <inheritdoc/>
public async ValueTask ShowGuildInfoAsync(uint guildId)
{
var data = await this.GetGuildDataAsync(guildId).ConfigureAwait(false);
if (data.Length == 0)
{
return;
}
var connection = this.Player.Connection;
if (connection is null)
{
return;
}
// guildInfo is the cached, serialized result of the GuildInformation-Class.
int Write()
{
var target = connection.Output.GetSpan(data.Length);
data.Span.CopyTo(target);
return data.Length;
}
await connection.SendAsync(Write).ConfigureAwait(false);
}
/// <inheritdoc/>
protected override Memory<byte> Serialize(Guild guild, uint guildId)
{
/*
* C1 3C 66 00
87 38 00 00 // guild number
00 // guild type
54 68 65 4F 6E 65 00 00 //TheOne - Maintain
41 76 61 6C 6F 6E 00 2B //Avalon - Assistant
18 88 88 81 18 66 66 81 18 61 16 81 18 61 16 81 18 66 66 81 18 61 16 81 18 61 16 81 18 61 16 81 //Guild Logo
F9 96 7C //?
*/
var array = new byte[GuildInformation.Length];
var result = new GuildInformation(array)
{
GuildId = guildId,
GuildName = guild.Name ?? string.Empty,
};
if (guild.AllianceGuild != null)
{
result.AllianceGuildName = guild.AllianceGuild.Name ?? string.Empty;
}
guild.Logo.CopyTo(result.Logo);
return array.AsMemory();
}
}

View File

@@ -0,0 +1,34 @@
// <copyright file="ShowGuildJoinRequestPlugIn.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameServer.RemoteView.Guild;
using System.Runtime.InteropServices;
using MUnique.OpenMU.GameLogic;
using MUnique.OpenMU.GameLogic.Views.Guild;
using MUnique.OpenMU.Network.Packets.ServerToClient;
using MUnique.OpenMU.PlugIns;
/// <summary>
/// The default implementation of the <see cref="IShowGuildJoinRequestPlugIn"/> which is forwarding everything to the game client with specific data packets.
/// </summary>
[PlugIn]
[Display(Name = nameof(PlugInResources.ShowGuildJoinRequestPlugIn_Name), Description = nameof(PlugInResources.ShowGuildJoinRequestPlugIn_Description), ResourceType = typeof(PlugInResources))]
[Guid("521ff03d-c8ad-44d9-a23d-8f98c4c174ae")]
public class ShowGuildJoinRequestPlugIn : IShowGuildJoinRequestPlugIn
{
private readonly RemotePlayer _player;
/// <summary>
/// Initializes a new instance of the <see cref="ShowGuildJoinRequestPlugIn"/> class.
/// </summary>
/// <param name="player">The player.</param>
public ShowGuildJoinRequestPlugIn(RemotePlayer player) => this._player = player;
/// <inheritdoc/>
public async ValueTask ShowGuildJoinRequestAsync(Player requester)
{
await this._player.Connection.SendGuildJoinRequestAsync(requester.Id).ConfigureAwait(false);
}
}

View File

@@ -0,0 +1,70 @@
// <copyright file="ShowGuildListPlugIn.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameServer.RemoteView.Guild;
using System.Runtime.InteropServices;
using MUnique.OpenMU.GameLogic.Views.Guild;
using MUnique.OpenMU.Network;
using MUnique.OpenMU.Network.Packets.ServerToClient;
using MUnique.OpenMU.Network.PlugIns;
using MUnique.OpenMU.PlugIns;
/// <summary>
/// The default implementation of the <see cref="IShowGuildListPlugIn"/> which is forwarding everything to the game client with specific data packets.
/// </summary>
[PlugIn]
[Display(Name = nameof(PlugInResources.ShowGuildListPlugIn_Name), Description = nameof(PlugInResources.ShowGuildListPlugIn_Description), ResourceType = typeof(PlugInResources))]
[Guid("f72a9968-100b-481f-aba1-1dd597fdad47")]
[MinimumClient(0, 90, ClientLanguage.Invariant)]
public class ShowGuildListPlugIn : IShowGuildListPlugIn
{
private readonly RemotePlayer _player;
/// <summary>
/// Initializes a new instance of the <see cref="ShowGuildListPlugIn"/> class.
/// </summary>
/// <param name="player">The player.</param>
public ShowGuildListPlugIn(RemotePlayer player) => this._player = player;
/// <inheritdoc/>
public async ValueTask ShowGuildListAsync(IReadOnlyCollection<OpenMU.Interfaces.GuildListEntry> players, Interfaces.Guild guild)
{
var connection = this._player.Connection;
if (connection is null)
{
return;
}
var playerCount = players.Count;
int Write()
{
var size = GuildListRef.GetRequiredSize(playerCount);
var span = connection.Output.GetSpan(size)[..size];
var packet = new GuildListRef(span)
{
GuildMemberCount = (byte)playerCount,
IsInGuild = playerCount > 0,
RivalGuildName = guild.Hostility?.Name ?? string.Empty,
CurrentScore = 0, // TODO: What is this? Maybe a rank?
TotalScore = (uint)guild.Score,
};
int i = 0;
foreach (var member in players)
{
var memberBlock = packet[i];
memberBlock.Name = member.PlayerName;
memberBlock.Role = member.PlayerPosition.Convert();
memberBlock.ServerId = member.ServerId;
memberBlock.ServerId2 = (byte)(member.ServerId == 0xFF ? 0x7F : 0x80 + member.ServerId);
i++;
}
return size;
}
await connection.SendAsync(Write).ConfigureAwait(false);
}
}

View File

@@ -0,0 +1,73 @@
// <copyright file="ShowGuildListPlugIn075.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameServer.RemoteView.Guild;
using System.Runtime.InteropServices;
using MUnique.OpenMU.GameLogic.Views.Guild;
using MUnique.OpenMU.Interfaces;
using MUnique.OpenMU.Network;
using MUnique.OpenMU.Network.Packets.ServerToClient;
using MUnique.OpenMU.Network.PlugIns;
using MUnique.OpenMU.PlugIns;
/// <summary>
/// The default implementation of the <see cref="IShowGuildListPlugIn"/> which is forwarding everything to the game client with specific data packets.
/// </summary>
[PlugIn]
[Display(Name = nameof(PlugInResources.ShowGuildListPlugIn075_Name), Description = nameof(PlugInResources.ShowGuildListPlugIn075_Description), ResourceType = typeof(PlugInResources))]
[Guid("1A7148DF-6E1B-47C7-9148-426F5E35F421")]
[MaximumClient(0, 89, ClientLanguage.Invariant)]
public class ShowGuildListPlugIn075 : IShowGuildListPlugIn
{
private readonly RemotePlayer _player;
/// <summary>
/// Initializes a new instance of the <see cref="ShowGuildListPlugIn075"/> class.
/// </summary>
/// <param name="player">The player.</param>
public ShowGuildListPlugIn075(RemotePlayer player) => this._player = player;
/// <inheritdoc/>
public async ValueTask ShowGuildListAsync(IReadOnlyCollection<GuildListEntry> players, Guild guild)
{
var connection = this._player.Connection;
if (connection is null)
{
return;
}
var sortedPlayers = players
.OrderBy(p => p.PlayerPosition != GuildPosition.GuildMaster)
.ThenBy(p => p.PlayerName)
.ToList();
var playerCount = sortedPlayers.Count;
int Write()
{
var size = GuildList075Ref.GetRequiredSize(playerCount);
var span = connection.Output.GetSpan(size)[..size];
var packet = new GuildList075Ref(span)
{
GuildMemberCount = (byte)playerCount,
IsInGuild = playerCount > 0,
CurrentScore = 0, // TODO
TotalScore = (uint)guild.Score,
};
int i = 0;
foreach (var member in sortedPlayers)
{
var memberBlock = packet[i];
memberBlock.Name = member.PlayerName;
memberBlock.ServerId = member.ServerId;
memberBlock.ServerId2 = (byte)(member.ServerId == 0xFF ? 0x7F : 0x80 + member.ServerId);
i++;
}
return size;
}
await connection.SendAsync(Write).ConfigureAwait(false);
}
}

View File

@@ -0,0 +1,33 @@
// <copyright file="ShowGuildMasterDialogPlugIn.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameServer.RemoteView.Guild;
using System.Runtime.InteropServices;
using MUnique.OpenMU.GameLogic.Views.Guild;
using MUnique.OpenMU.Network.Packets.ServerToClient;
using MUnique.OpenMU.PlugIns;
/// <summary>
/// The default implementation of the <see cref="IShowGuildMasterDialogPlugIn"/> which is forwarding everything to the game client with specific data packets.
/// </summary>
[PlugIn]
[Display(Name = nameof(PlugInResources.ShowGuildMasterDialogPlugIn_Name), Description = nameof(PlugInResources.ShowGuildMasterDialogPlugIn_Description), ResourceType = typeof(PlugInResources))]
[Guid("77d430e0-8bed-425b-8bb5-7bbafa9bfbff")]
public class ShowGuildMasterDialogPlugIn : IShowGuildMasterDialogPlugIn
{
private readonly RemotePlayer _player;
/// <summary>
/// Initializes a new instance of the <see cref="ShowGuildMasterDialogPlugIn"/> class.
/// </summary>
/// <param name="player">The player.</param>
public ShowGuildMasterDialogPlugIn(RemotePlayer player) => this._player = player;
/// <inheritdoc/>
public async ValueTask ShowGuildMasterDialogAsync()
{
await this._player.Connection.SendShowGuildMasterDialogAsync().ConfigureAwait(false);
}
}

View File

@@ -0,0 +1,53 @@
// <copyright file="ShowGuildRelationshipChangeResultPlugIn.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameServer.RemoteView.Guild;
using System.Runtime.InteropServices;
using MUnique.OpenMU.GameLogic.Views.Guild;
using MUnique.OpenMU.Network.Packets.ServerToClient;
using MUnique.OpenMU.PlugIns;
/// <summary>
/// The default implementation of the <see cref="IGuildRelationshipChangeResultPlugIn"/> which is forwarding everything to the game client with specific data packets.
/// </summary>
[PlugIn]
[Display(Name = nameof(PlugInResources.ShowGuildRelationshipChangeResultPlugIn_Name), Description = nameof(PlugInResources.ShowGuildRelationshipChangeResultPlugIn_Description), ResourceType = typeof(PlugInResources))]
[Guid("E6F7A8B9-C0D1-4E2F-3A4B-5C6D7E8F9A0B")]
public class ShowGuildRelationshipChangeResultPlugIn : IGuildRelationshipChangeResultPlugIn
{
private readonly RemotePlayer _player;
/// <summary>
/// Initializes a new instance of the <see cref="ShowGuildRelationshipChangeResultPlugIn"/> class.
/// </summary>
/// <param name="player">The player.</param>
public ShowGuildRelationshipChangeResultPlugIn(RemotePlayer player)
{
this._player = player;
}
/// <inheritdoc/>
public async ValueTask ShowRemoveResultAsync(
bool result,
GameLogic.Views.Guild.GuildRelationshipType relationshipType = GameLogic.Views.Guild.GuildRelationshipType.Alliance,
GameLogic.Views.Guild.GuildRelationshipRequestType requestType = GameLogic.Views.Guild.GuildRelationshipRequestType.Leave)
{
await this._player.Connection.SendRemoveAllianceGuildResultAsync(result, requestType.Convert(), relationshipType.Convert()).ConfigureAwait(false);
}
/// <inheritdoc/>
public async ValueTask ShowResultAsync(
GameLogic.Views.Guild.GuildRelationshipType relationshipType,
GameLogic.Views.Guild.GuildRelationshipRequestType requestType,
GameLogic.Views.Guild.GuildRelationshipChangeResultType result,
ushort? guildMasterId)
{
await this._player.Connection.SendGuildRelationshipChangeResultAsync(
relationshipType.Convert(),
requestType.Convert(),
result.Convert(),
guildMasterId ?? 0).ConfigureAwait(false);
}
}

View File

@@ -0,0 +1,38 @@
// <copyright file="ShowGuildRelationshipRequestPlugIn.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameServer.RemoteView.Guild;
using System.Runtime.InteropServices;
using MUnique.OpenMU.GameLogic;
using MUnique.OpenMU.GameLogic.Views;
using MUnique.OpenMU.GameLogic.Views.Guild;
using MUnique.OpenMU.Network.Packets.ServerToClient;
using MUnique.OpenMU.PlugIns;
/// <summary>
/// The default implementation of the <see cref="IShowGuildRelationshipRequestPlugIn"/> which is forwarding everything to the game client with specific data packets.
/// </summary>
[PlugIn]
[Display(Name = nameof(PlugInResources.ShowGuildRelationshipRequestPlugIn_Name), Description = nameof(PlugInResources.ShowGuildRelationshipRequestPlugIn_Description), ResourceType = typeof(PlugInResources))]
[Guid("F7A8B9C0-D1E2-4F3A-4B5C-6D7E8F9A0B1C")]
public class ShowGuildRelationshipRequestPlugIn : IShowGuildRelationshipRequestPlugIn
{
private readonly RemotePlayer _player;
/// <summary>
/// Initializes a new instance of the <see cref="ShowGuildRelationshipRequestPlugIn"/> class.
/// </summary>
/// <param name="player">The player.</param>
public ShowGuildRelationshipRequestPlugIn(RemotePlayer player) => this._player = player;
/// <inheritdoc/>
public async ValueTask ShowRequestAsync(Player requestingGuildMaster, GameLogic.Views.Guild.GuildRelationshipType relationshipType, GameLogic.Views.Guild.GuildRelationshipRequestType requestType)
{
await this._player.Connection.SendGuildRelationshipRequestAsync(
relationshipType.Convert(),
requestType.Convert(),
requestingGuildMaster.GetId(this._player)).ConfigureAwait(false);
}
}

View File

@@ -0,0 +1,36 @@
// <copyright file="ShowGuildWarDeclaredPlugIn.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameServer.RemoteView.Guild;
using System.Runtime.InteropServices;
using MUnique.OpenMU.GameLogic.Views.Guild;
using MUnique.OpenMU.Network.Packets.ServerToClient;
using MUnique.OpenMU.PlugIns;
/// <summary>
/// The default implementation of the <see cref="IShowGuildWarDeclaredPlugIn"/> which is forwarding everything to the game client with specific data packets.
/// </summary>
[PlugIn]
[Display(Name = nameof(PlugInResources.ShowGuildWarDeclaredPlugIn_Name), Description = nameof(PlugInResources.ShowGuildWarDeclaredPlugIn_Description), ResourceType = typeof(PlugInResources))]
[Guid("50393D5D-01F2-43F8-B5D7-243D91B905BC")]
public class ShowGuildWarDeclaredPlugIn : IShowGuildWarDeclaredPlugIn
{
private readonly RemotePlayer _player;
/// <summary>
/// Initializes a new instance of the <see cref="ShowGuildWarDeclaredPlugIn"/> class.
/// </summary>
/// <param name="player">The player.</param>
public ShowGuildWarDeclaredPlugIn(RemotePlayer player) => this._player = player;
/// <inheritdoc/>
public async ValueTask ShowDeclaredAsync()
{
if (this._player.GuildWarContext is { } guildWarContext)
{
await this._player.Connection.SendGuildWarDeclaredAsync(guildWarContext.EnemyTeamName, guildWarContext.WarType.Convert(), (byte)guildWarContext.Team).ConfigureAwait(false);
}
}
}

View File

@@ -0,0 +1,33 @@
// <copyright file="ShowGuildWarRequestPlugIn.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameServer.RemoteView.Guild;
using System.Runtime.InteropServices;
using MUnique.OpenMU.GameLogic.Views.Guild;
using MUnique.OpenMU.Network.Packets.ServerToClient;
using MUnique.OpenMU.PlugIns;
/// <summary>
/// The default implementation of the <see cref="IShowGuildWarRequestPlugIn"/> which is forwarding everything to the game client with specific data packets.
/// </summary>
[PlugIn]
[Display(Name = nameof(PlugInResources.ShowGuildWarRequestPlugIn_Name), Description = nameof(PlugInResources.ShowGuildWarRequestPlugIn_Description), ResourceType = typeof(PlugInResources))]
[Guid("128250B3-6CFC-4C89-BF8A-B50C892A78D3")]
public class ShowGuildWarRequestPlugIn : IShowGuildWarRequestPlugIn
{
private readonly RemotePlayer _player;
/// <summary>
/// Initializes a new instance of the <see cref="ShowGuildWarRequestPlugIn"/> class.
/// </summary>
/// <param name="player">The player.</param>
public ShowGuildWarRequestPlugIn(RemotePlayer player) => this._player = player;
/// <inheritdoc/>
public async ValueTask ShowRequestAsync(string requestingGuildName, GameLogic.GuildWar.GuildWarType warType)
{
await this._player.Connection.SendGuildWarRequestAsync(requestingGuildName, warType.Convert()).ConfigureAwait(false);
}
}

View File

@@ -0,0 +1,33 @@
// <copyright file="ShowGuildWarResultPlugIn.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameServer.RemoteView.Guild;
using System.Runtime.InteropServices;
using MUnique.OpenMU.GameLogic.Views.Guild;
using MUnique.OpenMU.Network.Packets.ServerToClient;
using MUnique.OpenMU.PlugIns;
/// <summary>
/// The default implementation of the <see cref="IShowGuildWarResultPlugIn"/> which is forwarding everything to the game client with specific data packets.
/// </summary>
[PlugIn]
[Display(Name = nameof(PlugInResources.ShowGuildWarResultPlugIn_Name), Description = nameof(PlugInResources.ShowGuildWarResultPlugIn_Description), ResourceType = typeof(PlugInResources))]
[Guid("991247B9-D4A3-466D-A7CE-2621843CA94F")]
public class ShowGuildWarResultPlugIn : IShowGuildWarResultPlugIn
{
private readonly RemotePlayer _player;
/// <summary>
/// Initializes a new instance of the <see cref="ShowGuildWarResultPlugIn"/> class.
/// </summary>
/// <param name="player">The player.</param>
public ShowGuildWarResultPlugIn(RemotePlayer player) => this._player = player;
/// <inheritdoc/>
public async ValueTask ShowResultAsync(string hostileGuildName, GuildWarResult result)
{
await this._player.Connection.SendGuildWarEndedAsync(result.Convert(), hostileGuildName).ConfigureAwait(false);
}
}

View File

@@ -0,0 +1,33 @@
// <copyright file="ShowShowGuildWarRequestResultPlugIn.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.GameServer.RemoteView.Guild;
using System.Runtime.InteropServices;
using MUnique.OpenMU.GameLogic.Views.Guild;
using MUnique.OpenMU.Network.Packets.ServerToClient;
using MUnique.OpenMU.PlugIns;
/// <summary>
/// The default implementation of the <see cref="IShowShowGuildWarRequestResultPlugIn"/> which is forwarding everything to the game client with specific data packets.
/// </summary>
[PlugIn]
[Display(Name = nameof(PlugInResources.ShowShowGuildWarRequestResultPlugIn_Name), Description = nameof(PlugInResources.ShowShowGuildWarRequestResultPlugIn_Description), ResourceType = typeof(PlugInResources))]
[Guid("7DDF834C-218B-4F35-B66C-54579BE485D5")]
public class ShowShowGuildWarRequestResultPlugIn : IShowShowGuildWarRequestResultPlugIn
{
private readonly RemotePlayer _player;
/// <summary>
/// Initializes a new instance of the <see cref="ShowShowGuildWarRequestResultPlugIn"/> class.
/// </summary>
/// <param name="player">The player.</param>
public ShowShowGuildWarRequestResultPlugIn(RemotePlayer player) => this._player = player;
/// <inheritdoc/>
public async ValueTask ShowResultAsync(GameLogic.Views.Guild.GuildWarRequestResult result)
{
await this._player.Connection.SendGuildWarRequestResultAsync(result.Convert()).ConfigureAwait(false);
}
}