MUIP server, GM command system
This commit is contained in:
parent
8be42d2ffb
commit
ace68414f7
22 changed files with 357 additions and 15 deletions
|
@ -26,7 +26,7 @@ public class AvatarRow : ExcelRow
|
|||
public uint MaxRank { get; set; } // 0x50
|
||||
public string[] RankUpCostList { get; set; } = []; // 0x58
|
||||
public uint MaxRankRepay { get; set; } // 0x60
|
||||
public uint[] SkillList { get; set; } // 0x68
|
||||
public uint[] SkillList { get; set; } = []; // 0x68
|
||||
[JsonConverter(typeof(JsonStringEnumConverter))]
|
||||
public AvatarBaseType AvatarBaseType { get; set; } // 0x70
|
||||
public string DefaultAvatarImagePath { get; set; } = string.Empty; // 0x78
|
||||
|
|
|
@ -7,17 +7,26 @@ enum RPGServiceType
|
|||
RPG_SERVICE_TYPE_SDK = 1;
|
||||
RPG_SERVICE_TYPE_GATESERVER = 2;
|
||||
RPG_SERVICE_TYPE_GAMESERVER = 3;
|
||||
RPG_SERVICE_TYPE_MUIPSERVER = 4;
|
||||
}
|
||||
|
||||
enum ServiceCommandType
|
||||
{
|
||||
SERVICE_COMMAND_TYPE_NONE = 0;
|
||||
SERVICE_COMMAND_TYPE_GMTALK_BY_MUIP = 10;
|
||||
|
||||
SERVICE_COMMAND_TYPE_BIND_CONTAINER = 100;
|
||||
SERVICE_COMMAND_TYPE_BIND_CONTAINER_RESULT = 101;
|
||||
SERVICE_COMMAND_TYPE_UNBIND_CONTAINER = 102;
|
||||
SERVICE_COMMAND_TYPE_FORWARD_GAME_MESSAGE = 103;
|
||||
}
|
||||
|
||||
message CmdGmtalkByMuip
|
||||
{
|
||||
uint64 session_id = 1;
|
||||
string msg = 2;
|
||||
}
|
||||
|
||||
message CmdBindContainer
|
||||
{
|
||||
uint64 session_id = 1;
|
||||
|
|
|
@ -9,7 +9,7 @@ using RPG.Services.Core.Session;
|
|||
namespace RPG.Services.Core.Extensions;
|
||||
public static class HostApplicationBuilderExtensions
|
||||
{
|
||||
public static HostApplicationBuilder SetupRPGService<TService, TCommandHandler>(this HostApplicationBuilder builder)
|
||||
public static IHostApplicationBuilder SetupRPGService<TService, TCommandHandler>(this IHostApplicationBuilder builder, bool stateless = false)
|
||||
where TService : RPGServiceBase
|
||||
where TCommandHandler : ServiceCommandHandler
|
||||
{
|
||||
|
@ -21,10 +21,11 @@ public static class HostApplicationBuilderExtensions
|
|||
|
||||
builder.Services.AddHostedService<TService>()
|
||||
.AddSingleton<ServiceManager>()
|
||||
.AddSingleton<SessionManager>()
|
||||
.AddSingleton<ServiceBox>()
|
||||
.AddSingleton<ServiceCommandHandler, TCommandHandler>();
|
||||
|
||||
if (!stateless) builder.Services.AddSingleton<SessionManager>();
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@ using RPG.Services.Gameserver.Modules.Attributes;
|
|||
using RPG.Services.Gameserver.Session;
|
||||
|
||||
namespace RPG.Services.Gameserver.Modules;
|
||||
|
||||
[GMAlias("adventure")]
|
||||
internal class AdventureModule : BaseModule
|
||||
{
|
||||
private readonly ExcelTables _tables;
|
||||
|
@ -13,6 +15,39 @@ internal class AdventureModule : BaseModule
|
|||
_tables = excelTables;
|
||||
}
|
||||
|
||||
[GMCommand("maze")]
|
||||
public Task OnGmEnterMaze(PlayerSession session, string[] args)
|
||||
{
|
||||
if (args.Length != 1) return Task.CompletedTask;
|
||||
|
||||
if (!uint.TryParse(args[0], out uint entryId))
|
||||
return Task.CompletedTask;
|
||||
|
||||
MapEntryRow? entry = _tables.GetExcelRow<MapEntryRow>(ExcelType.MapEntry, entryId);
|
||||
if (entry == null) return Task.CompletedTask;
|
||||
|
||||
Send(session, CmdType.CmdEnterMazeByServerScNotify, new EnterMazeByServerScNotify
|
||||
{
|
||||
Maze = new Maze
|
||||
{
|
||||
MapEntryId = entry.ID,
|
||||
Id = entry.PlaneID,
|
||||
Floor = new MazeFloor
|
||||
{
|
||||
FloorId = entry.FloorID,
|
||||
Scene = new SceneInfo
|
||||
{
|
||||
EntryId = entry.ID,
|
||||
PlaneId = entry.PlaneID,
|
||||
FloorId = entry.FloorID
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
[OnCommand(CmdType.CmdGetCurSceneInfoCsReq)]
|
||||
public Task OnCmdGetCurSceneInfoCsReq(PlayerSession session, ReadOnlyMemory<byte> _)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
namespace RPG.Services.Gameserver.Modules.Attributes;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
internal class GMAliasAttribute : Attribute
|
||||
{
|
||||
public string Alias { get; }
|
||||
|
||||
public GMAliasAttribute(string alias)
|
||||
{
|
||||
Alias = alias;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
namespace RPG.Services.Gameserver.Modules.Attributes;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
internal class GMCommandAttribute : Attribute
|
||||
{
|
||||
public string Command { get; }
|
||||
|
||||
public GMCommandAttribute(string command)
|
||||
{
|
||||
Command = command;
|
||||
}
|
||||
}
|
|
@ -11,14 +11,18 @@ namespace RPG.Services.Gameserver.Modules;
|
|||
internal class ModuleManager
|
||||
{
|
||||
private delegate Task ReqHandler(PlayerSession session, IServiceProvider serviceProvider, ReadOnlyMemory<byte> body);
|
||||
private static readonly ImmutableDictionary<CmdType, ReqHandler> s_handlers;
|
||||
private static readonly ImmutableDictionary<CmdType, ReqHandler> s_reqHandlers;
|
||||
|
||||
private delegate Task GmCommandHandler(IServiceProvider provider, PlayerSession session, string[] args);
|
||||
private static readonly ImmutableDictionary<string, ImmutableDictionary<string, GmCommandHandler>> s_gmCommandMap;
|
||||
|
||||
private readonly IServiceProvider _serviceProvider;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
static ModuleManager()
|
||||
{
|
||||
s_handlers = MapHandlers();
|
||||
s_reqHandlers = MapReqHandlers();
|
||||
s_gmCommandMap = MapGmCommandHandlers();
|
||||
}
|
||||
|
||||
public ModuleManager(IServiceProvider serviceProvider, ILogger<ModuleManager> logger)
|
||||
|
@ -27,9 +31,27 @@ internal class ModuleManager
|
|||
_logger = logger;
|
||||
}
|
||||
|
||||
public TModule Get<TModule>() where TModule : BaseModule
|
||||
{
|
||||
return _serviceProvider.GetRequiredService<TModule>();
|
||||
}
|
||||
|
||||
public async Task HandleGmCommandAsync(PlayerSession session, string[] args)
|
||||
{
|
||||
if (args.Length < 2) return;
|
||||
|
||||
if (s_gmCommandMap.TryGetValue(args[0], out var map))
|
||||
{
|
||||
if (map.TryGetValue(args[1], out GmCommandHandler? handler))
|
||||
{
|
||||
await handler(_serviceProvider, session, args[2..]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async Task HandleAsync(PlayerSession session, CmdType cmdType, ReadOnlyMemory<byte> body)
|
||||
{
|
||||
if (s_handlers.TryGetValue(cmdType, out var handler))
|
||||
if (s_reqHandlers.TryGetValue(cmdType, out var handler))
|
||||
{
|
||||
await handler(session, _serviceProvider, body);
|
||||
_logger.LogInformation("Successfully handled command of type {cmdType}", cmdType);
|
||||
|
@ -40,7 +62,7 @@ internal class ModuleManager
|
|||
}
|
||||
}
|
||||
|
||||
private static ImmutableDictionary<CmdType, ReqHandler> MapHandlers()
|
||||
private static ImmutableDictionary<CmdType, ReqHandler> MapReqHandlers()
|
||||
{
|
||||
var builder = ImmutableDictionary.CreateBuilder<CmdType, ReqHandler>();
|
||||
|
||||
|
@ -72,4 +94,43 @@ internal class ModuleManager
|
|||
|
||||
return builder.ToImmutable();
|
||||
}
|
||||
|
||||
private static ImmutableDictionary<string, ImmutableDictionary<string, GmCommandHandler>> MapGmCommandHandlers()
|
||||
{
|
||||
var builder = ImmutableDictionary.CreateBuilder<string, ImmutableDictionary<string, GmCommandHandler>>();
|
||||
|
||||
IEnumerable<Type> types = Assembly.GetExecutingAssembly().GetTypes()
|
||||
.Where(type => type.IsAssignableTo(typeof(BaseModule)) && !type.IsAbstract);
|
||||
|
||||
MethodInfo getServiceMethod = typeof(ServiceProviderServiceExtensions).GetMethod("GetRequiredService", [typeof(IServiceProvider)])!;
|
||||
|
||||
foreach (Type type in types)
|
||||
{
|
||||
GMAliasAttribute? aliasAttribute = type.GetCustomAttribute<GMAliasAttribute>();
|
||||
if (aliasAttribute == null) continue;
|
||||
|
||||
var commands = ImmutableDictionary.CreateBuilder<string, GmCommandHandler>();
|
||||
IEnumerable<MethodInfo> methods = type.GetMethods()
|
||||
.Where(method => method.GetCustomAttribute<GMCommandAttribute>() != null);
|
||||
|
||||
foreach (MethodInfo method in methods)
|
||||
{
|
||||
GMCommandAttribute attribute = method.GetCustomAttribute<GMCommandAttribute>()!;
|
||||
|
||||
ParameterExpression serviceProviderParam = Expression.Parameter(typeof(IServiceProvider));
|
||||
ParameterExpression sessionParam = Expression.Parameter(typeof(PlayerSession));
|
||||
ParameterExpression argsParam = Expression.Parameter(typeof(string[]));
|
||||
|
||||
MethodCallExpression getServiceCall = Expression.Call(getServiceMethod.MakeGenericMethod(type), serviceProviderParam);
|
||||
MethodCallExpression handlerCall = Expression.Call(getServiceCall, method, sessionParam, argsParam);
|
||||
|
||||
Expression<GmCommandHandler> lambda = Expression.Lambda<GmCommandHandler>(handlerCall, serviceProviderParam, sessionParam, argsParam);
|
||||
commands.Add(attribute.Command, lambda.Compile());
|
||||
}
|
||||
|
||||
builder.Add(aliasAttribute.Alias, commands.ToImmutable());
|
||||
}
|
||||
|
||||
return builder.ToImmutable();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,4 +66,15 @@ internal class GameserverCommandHandler : ServiceCommandHandler
|
|||
await session.HandleGameCommand((ushort)cmd.CmdType, cmd.Payload.Memory);
|
||||
}
|
||||
}
|
||||
|
||||
[ServiceCommand(ServiceCommandType.GmtalkByMuip)]
|
||||
public async Task OnCmdGmtalkByMuip(ServiceCommand command)
|
||||
{
|
||||
CmdGmtalkByMuip cmd = CmdGmtalkByMuip.Parser.ParseFrom(command.Body.Span);
|
||||
|
||||
if (_sessionManager.TryGet(cmd.SessionId, out PlayerSession? session))
|
||||
{
|
||||
await session.HandleGmTalkCommand(cmd.Msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,11 @@ internal class PlayerSession : RPGSession
|
|||
_moduleManager = _scope.ServiceProvider.GetRequiredService<ModuleManager>();
|
||||
}
|
||||
|
||||
public async Task HandleGmTalkCommand(string cmd)
|
||||
{
|
||||
await _moduleManager.HandleGmCommandAsync(this, cmd.Split(' '));
|
||||
}
|
||||
|
||||
public async Task HandleGameCommand(ushort cmdType, ReadOnlyMemory<byte> body)
|
||||
{
|
||||
await _moduleManager.HandleAsync(this, (CmdType)cmdType, body);
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
"ServiceType": "Gameserver"
|
||||
},
|
||||
"Nodes": [
|
||||
{
|
||||
"Type": "Muipserver",
|
||||
"Host": "127.0.0.1",
|
||||
"Port": "21031"
|
||||
},
|
||||
{
|
||||
"Type": "Gateserver",
|
||||
"Host": "127.0.0.1",
|
||||
|
|
|
@ -17,4 +17,8 @@
|
|||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Properties\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -3,6 +3,11 @@
|
|||
"ServiceType": "Gateserver"
|
||||
},
|
||||
"Nodes": [
|
||||
{
|
||||
"Type": "Muipserver",
|
||||
"Host": "127.0.0.1",
|
||||
"Port": "21031"
|
||||
},
|
||||
{
|
||||
"Type": "Gateserver",
|
||||
"Host": "127.0.0.1",
|
||||
|
|
53
RPG.Services.MUIP/Handlers/ApiHandler.cs
Normal file
53
RPG.Services.MUIP/Handlers/ApiHandler.cs
Normal file
|
@ -0,0 +1,53 @@
|
|||
using Google.Protobuf;
|
||||
using RPG.Network.Proto;
|
||||
using RPG.Services.Core.Network;
|
||||
using RPG.Services.Core.Network.Command;
|
||||
|
||||
namespace RPG.Services.MUIP.Handlers;
|
||||
|
||||
internal static class ApiHandler
|
||||
{
|
||||
private const string LogCategoryName = "MuipHttpApi";
|
||||
private const string GmTalkSessionIdQueryKey = "s_id";
|
||||
private const string GmTalkCommandQueryKey = "cmd";
|
||||
|
||||
private static ILogger? _logger;
|
||||
|
||||
public static IResult OnGmTalk(HttpContext ctx, ServiceBox services, ILoggerFactory loggerFactory)
|
||||
{
|
||||
_logger ??= loggerFactory.CreateLogger(LogCategoryName);
|
||||
|
||||
IQueryCollection query = ctx.Request.Query;
|
||||
if (!query.ContainsKey(GmTalkSessionIdQueryKey) || !query.ContainsKey(GmTalkCommandQueryKey))
|
||||
return Results.BadRequest();
|
||||
|
||||
string? sessionIdTxt = query[GmTalkSessionIdQueryKey];
|
||||
string? cmd = query[GmTalkCommandQueryKey];
|
||||
|
||||
if (cmd == null || sessionIdTxt == null)
|
||||
return Results.BadRequest();
|
||||
|
||||
if (!ulong.TryParse(sessionIdTxt, out ulong sessionId))
|
||||
return Results.BadRequest();
|
||||
|
||||
_logger.LogInformation("Received GM Talk request via HTTP, session id: {id}, cmd: {cmd}", sessionId, cmd);
|
||||
|
||||
SendServiceCommand(services, ServiceCommandType.GmtalkByMuip, new CmdGmtalkByMuip
|
||||
{
|
||||
SessionId = sessionId,
|
||||
Msg = cmd
|
||||
}, RPGServiceType.Gameserver);
|
||||
|
||||
return Results.Ok("Request forwarded to Gameserver");
|
||||
}
|
||||
|
||||
private static void SendServiceCommand<TBody>(ServiceBox services, ServiceCommandType commandType, TBody body, RPGServiceType target) where TBody : IMessage<TBody>
|
||||
{
|
||||
ServiceCommand command = new(services.CurrentType, commandType, body.ToByteArray());
|
||||
|
||||
byte[] buffer = GC.AllocateUninitializedArray<byte>(command.Body.Length + 7);
|
||||
ServiceCommandEncoder.EncodeCommand(command, buffer);
|
||||
|
||||
services.SendToService(target, buffer);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
using RPG.Services.Core.Network;
|
||||
using RPG.Services.Core.Network.Command;
|
||||
|
||||
namespace RPG.Services.MUIP.Network.Command;
|
||||
|
||||
internal class MuipserverCommandHandler : ServiceCommandHandler
|
||||
{
|
||||
public MuipserverCommandHandler(ILogger<ServiceCommandHandler> logger, ServiceBox services) : base(logger, services)
|
||||
{
|
||||
}
|
||||
}
|
23
RPG.Services.MUIP/Program.cs
Normal file
23
RPG.Services.MUIP/Program.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
using RPG.Services.MUIP.Handlers;
|
||||
using RPG.Services.Core.Extensions;
|
||||
using RPG.Services.MUIP.Network.Command;
|
||||
|
||||
namespace RPG.Services.MUIP;
|
||||
|
||||
internal static class Program
|
||||
{
|
||||
private static async Task Main(string[] args)
|
||||
{
|
||||
Console.Title = "Snowflake | MUIP";
|
||||
|
||||
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
|
||||
builder.WebHost.UseUrls("http://*:1337");
|
||||
builder.SetupRPGService<RPGMuipserver, MuipserverCommandHandler>(true);
|
||||
|
||||
WebApplication app = builder.Build();
|
||||
|
||||
app.MapGet("/api/gmtalk", ApiHandler.OnGmTalk);
|
||||
|
||||
await app.RunAsync();
|
||||
}
|
||||
}
|
29
RPG.Services.MUIP/Properties/launchSettings.json
Normal file
29
RPG.Services.MUIP/Properties/launchSettings.json
Normal file
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||
"iisSettings": {
|
||||
"windowsAuthentication": false,
|
||||
"anonymousAuthentication": true,
|
||||
"iisExpress": {
|
||||
"applicationUrl": "http://localhost:13849",
|
||||
"sslPort": 0
|
||||
}
|
||||
},
|
||||
"profiles": {
|
||||
"http": {
|
||||
"commandName": "Project",
|
||||
"dotnetRunMessages": true,
|
||||
"launchBrowser": true,
|
||||
"applicationUrl": "http://localhost:5001",
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
},
|
||||
"IIS Express": {
|
||||
"commandName": "IISExpress",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
13
RPG.Services.MUIP/RPG.Services.MUIP.csproj
Normal file
13
RPG.Services.MUIP/RPG.Services.MUIP.csproj
Normal file
|
@ -0,0 +1,13 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\RPG.Services.Core\RPG.Services.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
10
RPG.Services.MUIP/RPGMuipserver.cs
Normal file
10
RPG.Services.MUIP/RPGMuipserver.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
using RPG.Services.Core;
|
||||
|
||||
namespace RPG.Services.MUIP;
|
||||
|
||||
internal class RPGMuipserver : RPGServiceBase
|
||||
{
|
||||
public RPGMuipserver(ServiceManager serviceManager) : base(serviceManager)
|
||||
{
|
||||
}
|
||||
}
|
8
RPG.Services.MUIP/appsettings.Development.json
Normal file
8
RPG.Services.MUIP/appsettings.Development.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
}
|
||||
}
|
29
RPG.Services.MUIP/appsettings.json
Normal file
29
RPG.Services.MUIP/appsettings.json
Normal file
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Microsoft.AspNetCore": "Warning"
|
||||
}
|
||||
},
|
||||
"AllowedHosts": "*",
|
||||
"Service": {
|
||||
"ServiceType": "Muipserver"
|
||||
},
|
||||
"Nodes": [
|
||||
{
|
||||
"Type": "Muipserver",
|
||||
"Host": "127.0.0.1",
|
||||
"Port": "21031"
|
||||
},
|
||||
{
|
||||
"Type": "Gateserver",
|
||||
"Host": "127.0.0.1",
|
||||
"Port": "21051"
|
||||
},
|
||||
{
|
||||
"Type": "Gameserver",
|
||||
"Host": "127.0.0.1",
|
||||
"Port": "21081"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
using Microsoft.AspNetCore.Http.HttpResults;
|
||||
using RPG.Services.SDK.Models;
|
||||
using RPG.Services.SDK.Models.Region;
|
||||
|
||||
namespace RPG.Services.SDK.Handlers;
|
||||
|
@ -14,7 +13,7 @@ public static class DispatchHandler
|
|||
{
|
||||
Retcode = 0,
|
||||
TopServerRegionName = "Snowflake",
|
||||
RegionList =
|
||||
RegionList =
|
||||
[
|
||||
new RegionInfo
|
||||
{
|
||||
|
|
|
@ -3,27 +3,29 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31903.59
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RPG.Network.Proto", "RPG.Network.Proto\RPG.Network.Proto.csproj", "{7DA70126-3F73-407B-A024-5856F354FA97}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RPG.Network.Proto", "RPG.Network.Proto\RPG.Network.Proto.csproj", "{7DA70126-3F73-407B-A024-5856F354FA97}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RPG.GameCore", "RPG.GameCore\RPG.GameCore.csproj", "{74042D70-7EA0-4348-9BDB-D1E5D0FC868A}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RPG.GameCore", "RPG.GameCore\RPG.GameCore.csproj", "{74042D70-7EA0-4348-9BDB-D1E5D0FC868A}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Framework", "Framework", "{0FF9D567-C413-43F0-9EDF-09D4D36154B7}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Services", "Services", "{F199706E-4A92-4A2F-BDDD-25DA4691D43E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RPG.Services.SDK", "RPG.Services.SDK\RPG.Services.SDK.csproj", "{855DA130-974F-4CE8-8DB5-2BD59DC2C3AA}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RPG.Services.SDK", "RPG.Services.SDK\RPG.Services.SDK.csproj", "{855DA130-974F-4CE8-8DB5-2BD59DC2C3AA}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RPG.Services.Gateserver", "RPG.Services.Gateserver\RPG.Services.Gateserver.csproj", "{EB7A2038-E2AF-4565-944C-D850D6AEAEED}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RPG.Services.Gateserver", "RPG.Services.Gateserver\RPG.Services.Gateserver.csproj", "{EB7A2038-E2AF-4565-944C-D850D6AEAEED}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RPG.Services.Gameserver", "RPG.Services.Gameserver\RPG.Services.Gameserver.csproj", "{565F9857-3E97-4363-9A5D-05CED8718116}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RPG.Services.Gameserver", "RPG.Services.Gameserver\RPG.Services.Gameserver.csproj", "{565F9857-3E97-4363-9A5D-05CED8718116}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RPG.Services.Core", "RPG.Services.Core\RPG.Services.Core.csproj", "{1B434662-DEC9-40C9-A709-CE87026191D9}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RPG.Services.Core", "RPG.Services.Core\RPG.Services.Core.csproj", "{1B434662-DEC9-40C9-A709-CE87026191D9}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D96091AB-B78F-4092-ADEF-7A4D9F1B90C6}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.editorconfig = .editorconfig
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RPG.Services.MUIP", "RPG.Services.MUIP\RPG.Services.MUIP.csproj", "{2E029A8A-8878-4B71-B72B-2881CDE83B71}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -54,6 +56,10 @@ Global
|
|||
{1B434662-DEC9-40C9-A709-CE87026191D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1B434662-DEC9-40C9-A709-CE87026191D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1B434662-DEC9-40C9-A709-CE87026191D9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{2E029A8A-8878-4B71-B72B-2881CDE83B71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{2E029A8A-8878-4B71-B72B-2881CDE83B71}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{2E029A8A-8878-4B71-B72B-2881CDE83B71}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{2E029A8A-8878-4B71-B72B-2881CDE83B71}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -65,6 +71,7 @@ Global
|
|||
{EB7A2038-E2AF-4565-944C-D850D6AEAEED} = {F199706E-4A92-4A2F-BDDD-25DA4691D43E}
|
||||
{565F9857-3E97-4363-9A5D-05CED8718116} = {F199706E-4A92-4A2F-BDDD-25DA4691D43E}
|
||||
{1B434662-DEC9-40C9-A709-CE87026191D9} = {0FF9D567-C413-43F0-9EDF-09D4D36154B7}
|
||||
{2E029A8A-8878-4B71-B72B-2881CDE83B71} = {F199706E-4A92-4A2F-BDDD-25DA4691D43E}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {9B5CE103-882A-419D-8FA3-89C8642687F6}
|
||||
|
|
Loading…
Reference in a new issue