diff --git a/src/Configuration/ApiServerConfig.cs b/src/Configuration/ApiServerConfig.cs index 58b079b..1a8d513 100644 --- a/src/Configuration/ApiServerConfig.cs +++ b/src/Configuration/ApiServerConfig.cs @@ -4,6 +4,7 @@ public class ApiServerConfig { public string MMOAdress { get; set; } = "127.0.0.1"; public int MMOPort { get; set; } = 9933; + public int MMOHttpApiPort { get; set; } = 9934; public uint MMOSupportMinVersion { get; set; } = 0; public DbProviders DbProvider { get; set; } = DbProviders.SQLite; diff --git a/src/Controllers/Common/ContentController.cs b/src/Controllers/Common/ContentController.cs index 6b07c24..c012104 100644 --- a/src/Controllers/Common/ContentController.cs +++ b/src/Controllers/Common/ContentController.cs @@ -22,6 +22,7 @@ public class ContentController : Controller { private GameDataService gameDataService; private DisplayNamesService displayNamesService; private NeighborhoodService neighborhoodService; + private MMOCommunicationService mMOCommunicationService; private Random random = new Random(); private readonly IOptions config; @@ -36,6 +37,7 @@ public class ContentController : Controller { GameDataService gameDataService, DisplayNamesService displayNamesService, NeighborhoodService neighborhoodService, + MMOCommunicationService mMOCommunicationService, IOptions config ) { this.ctx = ctx; @@ -48,6 +50,7 @@ public class ContentController : Controller { this.gameDataService = gameDataService; this.displayNamesService = displayNamesService; this.neighborhoodService = neighborhoodService; + this.mMOCommunicationService = mMOCommunicationService; this.config = config; } @@ -1608,13 +1611,14 @@ public class ContentController : Controller { [Produces("application/xml")] [Route("ContentWebService.asmx/SetScene")] // used by World of Jumpstart [VikingSession] - public IActionResult SetScene(Viking viking, [FromForm] string sceneName, [FromForm] string contentXml) { + public IActionResult SetScene(Viking viking, [FromForm] string sceneName, [FromForm] string contentXml, [FromForm] string apiToken) { SceneData? existingScene = viking.SceneData.FirstOrDefault(e => e.SceneName == sceneName); if(existingScene is not null) { existingScene.XmlData = contentXml; ctx.SaveChanges(); + mMOCommunicationService.SendPacketToRoom(apiToken, sceneName + '_' + viking.Uid.ToString(), "SNE", new string[] { "SNE", "-1", contentXml, "8" }); return Ok(true); } else @@ -1634,13 +1638,14 @@ public class ContentController : Controller { [Produces("application/xml")] [Route("ContentWebService.asmx/SetHouse")] // used by World Of Jumpstart [VikingSession] - public IActionResult SetHouse(Viking viking, [FromForm] string contentXml) { + public IActionResult SetHouse(Viking viking, [FromForm] string contentXml, [FromForm] string apiToken) { Util.SavedData.Set( viking, Util.SavedData.House(), contentXml ); ctx.SaveChanges(); + mMOCommunicationService.SendPacketToRoom(apiToken, $"MyNeighborhood_{viking.Uid}", "SNE", new string[] { "SNE", "-1", viking.Uid.ToString(), "10" }); // hardcoding neighborhood here for now, client doesn't send a scene name here return Ok(true); } @@ -1648,8 +1653,8 @@ public class ContentController : Controller { [Produces("application/xml")] [Route("ContentWebService.asmx/SetNeighbor")] // used by World Of Jumpstart [VikingSession(UseLock=true)] - public IActionResult SetNeighbor(Viking viking, string neighboruserid, int slot) { - return Ok(neighborhoodService.SaveNeighbors(viking, neighboruserid, slot)); + public IActionResult SetNeighbor(Viking viking, string neighboruserid, int slot, string apiToken) { + return Ok(neighborhoodService.SaveNeighbors(viking, neighboruserid, slot, apiToken)); } [HttpPost] diff --git a/src/Program.cs b/src/Program.cs index 1eca9c4..5bbe5c6 100644 --- a/src/Program.cs +++ b/src/Program.cs @@ -39,6 +39,7 @@ builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); +builder.Services.AddScoped(); bool assetServer = builder.Configuration.GetSection("AssetServer").GetValue("Enabled"); string assetIP = builder.Configuration.GetSection("AssetServer").GetValue("ListenIP"); diff --git a/src/Services/MMOCommunicationService.cs b/src/Services/MMOCommunicationService.cs new file mode 100644 index 0000000..899080f --- /dev/null +++ b/src/Services/MMOCommunicationService.cs @@ -0,0 +1,92 @@ +using System; +using System.Data.Common; +using System.Text.Json; +using Microsoft.Extensions.Options; +using sodoff.Configuration; +using sodoff.Model; + +namespace sodoff.Services; + +public class MMOCommunicationService +{ + public readonly DBContext dBContext; + public readonly HttpClient httpClient; + public readonly IOptions config; + + public MMOCommunicationService(DBContext dBContext, IOptions options) + { + this.dBContext = dBContext; + config = options; + httpClient = new HttpClient(); + } + + public bool SendPacketToRoom(string apiToken, string roomName, string cmd, string[] args) + { + var serializedArgs = JsonSerializer.Serialize(args); + + FormUrlEncodedContent form = new FormUrlEncodedContent(new Dictionary + { + { "apiToken", apiToken }, + { "roomName", roomName }, + { "cmd", cmd }, + { "serializedArgs", serializedArgs } + }); + try + { + var result = httpClient.PostAsync($"http://{config.Value.MMOAdress}:{config.Value.MMOHttpApiPort}/mmo/update/SendPacketToRoom", form)?.Result; + if (result != null && result.StatusCode == System.Net.HttpStatusCode.OK) return true; + else return false; + } catch (AggregateException ex) + { + Console.WriteLine("MMO Communication Failiure. Please Investigate - " + ex.Message); + return false; + } + } + + public bool SendPacketToPlayer(string apiToken, string userId, string cmd, string[] args) + { + var argsSerialized = JsonSerializer.Serialize(args); + FormUrlEncodedContent form = new FormUrlEncodedContent(new Dictionary + { + { "apiToken", apiToken }, + { "userId", userId }, + { "cmd", cmd }, + { "serializedArgs", argsSerialized } + }); + + try + { + var result = httpClient.PostAsync($"http://{config.Value.MMOAdress}:{config.Value.MMOHttpApiPort}/mmo/update/SendPacketToPlayer", form)?.Result; + if (result != null && result.StatusCode == System.Net.HttpStatusCode.OK) return true; + else return false; + } + catch (AggregateException ex) + { + Console.WriteLine("MMO Communication Failiure. Please Investigate - " + ex.Message); + return false; + } + } + + public bool UpdateRoomVarsInRoom(string apiToken, string roomName, Dictionary vars) + { + var varsSerialized = JsonSerializer.Serialize(vars); + FormUrlEncodedContent form = new FormUrlEncodedContent(new Dictionary + { + { "apiToken", apiToken }, + { "roomName", roomName }, + { "serializedVars", varsSerialized } + }); + + try + { + var result = httpClient.PostAsync($"http://{config.Value.MMOAdress}:{config.Value.MMOHttpApiPort}/mmo/update/UpdateRoomVarsInRoom", form)?.Result; + if (result != null && result.StatusCode == System.Net.HttpStatusCode.OK) return true; + else return false; + } + catch (AggregateException ex) + { + Console.WriteLine("MMO Communication Failiure. Please Investigate - " + ex.Message); + return false; + } + } +} diff --git a/src/Services/NeighborhoodService.cs b/src/Services/NeighborhoodService.cs index 8bec07c..7dfec9f 100644 --- a/src/Services/NeighborhoodService.cs +++ b/src/Services/NeighborhoodService.cs @@ -10,6 +10,7 @@ namespace sodoff.Services public class NeighborhoodService { private readonly DBContext ctx; + private readonly MMOCommunicationService mMOCommunicationService; // default neighborhood slots (NPCs) Guid slot0 = new Guid("aaaaaaaa-0000-0000-0000-000000000000"); @@ -18,12 +19,14 @@ namespace sodoff.Services Guid slot3 = new Guid("dddddddd-0000-0000-0000-000000000000"); Guid slot4 = new Guid("eeeeeeee-0000-0000-0000-000000000000"); - public NeighborhoodService(DBContext ctx) { + public NeighborhoodService(DBContext ctx, MMOCommunicationService mMOCommunicationService) { this.ctx = ctx; + this.mMOCommunicationService = mMOCommunicationService; } - public bool SaveNeighbors(Viking viking, string neighborUid, int slot) { + public bool SaveNeighbors(Viking viking, string neighborUid, int slot, string apiToken) { Model.Neighborhood? neighborhood = viking.Neighborhood; + Dictionary neighborRoomVars = new Dictionary(); if (neighborhood == null) // if viking has no neighborhood yet, create a default one viking.Neighborhood = new Model.Neighborhood { @@ -39,21 +42,28 @@ namespace sodoff.Services switch (slot) { case 0: viking.Neighborhood.Slot0 = new Guid(neighborUid); + neighborRoomVars.Add("S0", viking.Neighborhood.Slot0.ToString()); break; case 1: viking.Neighborhood.Slot1 = new Guid(neighborUid); + neighborRoomVars.Add("S1", viking.Neighborhood.Slot1.ToString()); break; case 2: viking.Neighborhood.Slot2 = new Guid(neighborUid); + neighborRoomVars.Add("S2", viking.Neighborhood.Slot2.ToString()); break; case 3: viking.Neighborhood.Slot3 = new Guid(neighborUid); + neighborRoomVars.Add("S3", viking.Neighborhood.Slot3.ToString()); break; case 4: viking.Neighborhood.Slot4 = new Guid(neighborUid); + neighborRoomVars.Add("S4", viking.Neighborhood.Slot4.ToString()); break; } + mMOCommunicationService.UpdateRoomVarsInRoom(apiToken, $"MyNeighborhood_{viking.Uid}", neighborRoomVars); // once again hardcoding neighborhood + ctx.SaveChanges(); return true; }