diff --git a/src/Controllers/Common/ContentController.cs b/src/Controllers/Common/ContentController.cs index 4dc3153..2f364e3 100644 --- a/src/Controllers/Common/ContentController.cs +++ b/src/Controllers/Common/ContentController.cs @@ -1389,6 +1389,7 @@ public class ContentController : Controller { List allParties = ctx.Parties.ToList(); List userParties = new List(); + uint gameID = ClientVersion.GetGameID(apiKey); foreach(var party in allParties) { if(DateTime.UtcNow >= party.ExpirationDate) @@ -1399,42 +1400,26 @@ public class ContentController : Controller { continue; } + // Only send parties to their respective games. + if (gameID != party.GameID) continue; Viking viking = ctx.Vikings.FirstOrDefault(e => e.Id == party.VikingId); AvatarData avatarData = XmlUtil.DeserializeXml(viking.AvatarSerialized); - UserParty userParty = new UserParty - { - DisplayName = avatarData.DisplayName, + + + + UserParty userParty = new UserParty { + DisplayName = $"{avatarData.DisplayName}'s {party.Descriptor} Party", UserName = avatarData.DisplayName, ExpirationDate = party.ExpirationDate, - Icon = party.LocationIconAsset, + Icon = party.IconAsset, Location = party.Location, + LocationIcon = party.LocationIconAsset, PrivateParty = party.PrivateParty!.Value, UserID = viking.Uid }; - if (party.Location == "MyNeighborhood") userParty.DisplayName = $"{userParty.UserName}'s Block Party"; - if (party.Location == "MyVIPRoomInt") userParty.DisplayName = $"{userParty.UserName}'s VIP Party"; - if (party.Location == "MyPodInt") { - // Only way to do this without adding another column to the table. - if (party.AssetBundle == "RS_DATA/PfMyPodBirthdayParty.unity3d/PfMyPodBirthdayParty") { - userParty.DisplayName = $"{userParty.UserName}'s Pod Birthday Party"; - } else { - userParty.DisplayName = $"{userParty.UserName}'s Pod Party"; - } - } - - uint gameID = ClientVersion.GetGameID(apiKey); - // Send only JumpStart parties to JumpStart - if (gameID == ClientVersion.WoJS - && (party.Location == "MyNeighborhood" - || party.Location == "MyVIPRoomInt")) { - userParties.Add(userParty); - // Send only Math Blaster parties to Math Blaster - } else if (gameID == ClientVersion.MB - && party.Location == "MyPodInt") { - userParties.Add(userParty); - } + userParties.Add(userParty); } return Ok(new UserPartyData { NonBuddyParties = userParties.ToArray() }); @@ -1466,11 +1451,12 @@ public class ContentController : Controller { AvatarData avatarData = XmlUtil.DeserializeXml(viking.AvatarSerialized); UserPartyComplete userPartyComplete = new UserPartyComplete { - DisplayName = avatarData.DisplayName, + DisplayName = $"{avatarData.DisplayName}'s {party.Descriptor} Party", UserName = avatarData.DisplayName, ExpirationDate = party.ExpirationDate, - Icon = party.LocationIconAsset, + Icon = party.IconAsset, Location = party.Location, + LocationIcon = party.LocationIconAsset, PrivateParty = party.PrivateParty!.Value, UserID = viking.Uid, AssetBundle = party.AssetBundle @@ -1492,55 +1478,40 @@ public class ContentController : Controller { { ItemData itemData = itemService.GetItem(itemId); - // create a party based on bought itemid - Party party = new Party - { - PrivateParty = false - }; - string? partyType = itemData.Attribute?.FirstOrDefault(a => a.Key == "PartyType").Value; if (partyType is null) { return Ok(null); } - uint gameVersion = ClientVersion.GetVersion(apiKey); - if (partyType == "Default") { - if (gameVersion == ClientVersion.MB) { - party.Location = "MyPodInt"; - party.LocationIconAsset = "RS_DATA/PfUiPartiesListMB.unity3d/IcoMbPartyDefault"; - party.AssetBundle = "RS_DATA/PfMyPodParty.unity3d/PfMyPodParty"; - } else { - party.Location = "MyNeighborhood"; - party.LocationIconAsset = "RS_DATA/PfUiPartiesList.unity3d/IcoPartyLocationMyNeighborhood"; - party.AssetBundle = "RS_DATA/PfMyNeighborhoodParty.unity3d/PfMyNeighborhoodParty"; - } - } else if (partyType == "VIPRoom") { - party.Location = "MyVIPRoomInt"; - party.LocationIconAsset = "RS_DATA/PfUiPartiesList.unity3d/IcoPartyDefault"; - party.AssetBundle = "RS_DATA/PfMyVIPRoomIntPartyGroup.unity3d/PfMyVIPRoomIntPartyGroup"; - } else if (partyType == "Birthday") { - party.Location = "MyPodInt"; - party.LocationIconAsset = "RS_DATA/PfUiPartiesListMB.unity3d/IcoMbPartyBirthday"; - party.AssetBundle = "RS_DATA/PfMyPodBirthdayParty.unity3d/PfMyPodBirthdayParty"; - } else { - Console.WriteLine($"Unsupported partyType = {partyType}"); - return Ok(null); - } + uint gameID = ClientVersion.GetGameID(apiKey); - party.ExpirationDate = DateTime.UtcNow.AddMinutes( - Int32.Parse(itemData.Attribute.FirstOrDefault(a => a.Key == "Time").Value) - ); + PartyInfo? info = xmlDataService.GetParty(gameID, partyType); + if (info == null) return Ok(null); // check if party already exists - if (viking.Parties.FirstOrDefault(e => e.Location == party.Location) != null) return Ok(null); + if (viking.Parties.Any(e => e.Location == info.Location)) return Ok(null); + + // create a party based on bought itemid + Party party = new Party { + Location = info.Location, + IconAsset = info.Icon, + LocationIconAsset = xmlDataService.GetPartyLocation(info) ?? "", + AssetBundle = info.Bundle, + PrivateParty = false, + GameID = gameID, + ExpirationDate = DateTime.UtcNow.AddMinutes( + Int32.Parse(itemData.Attribute.FirstOrDefault(a => a.Key == "Time").Value) + ), + Descriptor = info.Descriptor + }; // take away coins viking.AchievementPoints.FirstOrDefault(e => e.Type == (int)AchievementPointTypes.GameCurrency)!.Value -= itemData.Cost; viking.Parties.Add(party); ctx.SaveChanges(); - + return Ok(true); } diff --git a/src/Model/Party.cs b/src/Model/Party.cs index dd4b5ab..032c89b 100644 --- a/src/Model/Party.cs +++ b/src/Model/Party.cs @@ -13,9 +13,12 @@ namespace sodoff.Model public int VikingId { get; set; } public DateTime ExpirationDate { get; set; } = DateTime.UtcNow; public bool? PrivateParty { get; set; } + public string IconAsset { get; set; } = null!; public string LocationIconAsset { get; set; } = null!; public string AssetBundle { get; set; } = null!; [JsonIgnore] public virtual Viking? Viking { get; set; } + public uint? GameID { get; set; } + public string? Descriptor { get; set; } } } diff --git a/src/Program.cs b/src/Program.cs index 25462b4..2ec6b86 100644 --- a/src/Program.cs +++ b/src/Program.cs @@ -30,6 +30,7 @@ builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); +builder.Services.AddSingleton(); builder.Services.AddScoped(); builder.Services.AddScoped(); diff --git a/src/Resources/parties_info.xml b/src/Resources/parties_info.xml new file mode 100644 index 0000000..ab208b2 --- /dev/null +++ b/src/Resources/parties_info.xml @@ -0,0 +1,89 @@ + + + + MyNeighborhood + RS_DATA/Parties01.unity3d/IcoPartyLocationMyNeighborhood + + + MyVIPRoomInt + RS_DATA/Parties01.unity3d/IcoPartyLocationVIPRoom + + + + + 0x01000000 + MyNeighborhood + Default + RS_DATA/Parties01.unity3d/IcoPartyDefault + RS_DATA/PfMyNeighborhoodParty.unity3d/PfMyNeighborhoodParty + Block + + + 0x01000000 + MyVIPRoomInt + VIPRoom + RS_DATA/Parties01.unity3d/IcoPartyDefault + RS_DATA/PfMyVIPRoomIntPartyGroup.unity3d/PfMyVIPRoomIntPartyGroup + VIP + + + 0x01000000 + MyVIPRoomInt + Holiday + RS_DATA/Parties01.unity3d/IcoStorePartyXmasDefault + RS_DATA/PfMyVIPRoomIntXmasGroup.unity3d/PfMyVIPRoomIntXmasGroup + Holiday + + + + + 0x08000000 + MyPodInt + Default + RS_DATA/PfUiPartiesListMB.unity3d/IcoMbPartyDefault + RS_DATA/PfUiPartiesListMB.unity3d/IcoMbPartyDefault + Pod + + + 0x08000000 + MyPodInt + Birthday + RS_DATA/PfUiPartiesListMB.unity3d/IcoMbPartyBirthday + RS_DATA/PfMyPodBirthdayParty.unity3d/PfMyPodBirthdayParty + Birthday + + + + + 0x02000000 + MyLoungeSSInt + Default + RS_DATA/SSParties.unity3d/IcoSSStorePartyDefault + RS_DATA/PfSsRoomInteriorPartyGroup.unity3d/PfSsRoomInteriorPartyGroup + Lounge + + + 0x02000000 + MyLoungeSSInt + Birthday + RS_DATA/SSParties.unity3d/IcoSSStorePartyBirthdayDefault + RS_DATA/PfSsRoomInteriorBirthdayGroup.unity3d/PfSsRoomInteriorBirthdayGroup + Birthday + + + 0x02000000 + MyLoungeSSInt + NewYears + RS_DATA/SSParties.unity3d/IcoSSStorePartyNewYearDefault + RS_DATA/PfSsRoomInteriorNewYearGroup.unity3d/PfSsRoomInteriorNewYearGroup + New Years + + + 0x02000000 + MyLoungeSSInt + Holiday + RS_DATA/SSParties.unity3d/IcoSSStorePartyHolidayDefault + RS_DATA/PfSsRoomInteriorHolidayGroup.unity3d/PfSsRoomInteriorHolidayGroup + Holiday + + \ No newline at end of file diff --git a/src/Schema/PartiesInfo.cs b/src/Schema/PartiesInfo.cs new file mode 100644 index 0000000..4228387 --- /dev/null +++ b/src/Schema/PartiesInfo.cs @@ -0,0 +1,54 @@ +using sodoff.Util; +using System.Xml.Serialization; + +namespace sodoff.Schema; + +[XmlRoot(ElementName = "PartiesInfo", Namespace = "")] +[Serializable] +public class PartiesInfo { + [XmlElement(ElementName = "Location")] + public PartyIconData[] IconData { + get { return LocationIcons.Select(i => new PartyIconData {Name = i.Key, Icon = i.Value}).ToArray(); } + set { LocationIcons = value.ToDictionary(i => i.Name, i => i.Icon); } + } + + [XmlIgnore] + public Dictionary LocationIcons; + + [XmlElement(ElementName = "Party")] + public PartyInfo[] Parties; +} + +public class PartyIconData { + [XmlElement("Name")] + public string Name; + + [XmlElement("Icon")] + public string Icon; +} + +public class PartyInfo { + [XmlElement("Version")] + public string Version { + get { return GameID.ToString("X"); } + set { GameID = XmlUtil.HexToUint(value); } + } + + [XmlIgnore] + public uint GameID; + + [XmlElement("Location")] + public string Location; + + [XmlElement("Type")] + public string Type; + + [XmlElement("Icon")] + public string Icon; + + [XmlElement("AssetBundle")] + public string Bundle; + + [XmlElement("Descriptor")] + public string? Descriptor; +} \ No newline at end of file diff --git a/src/Services/PartyService.cs b/src/Services/PartyService.cs new file mode 100644 index 0000000..1cd792b --- /dev/null +++ b/src/Services/PartyService.cs @@ -0,0 +1,33 @@ +using sodoff.Schema; +using sodoff.Util; + +namespace sodoff.Services; + +public class PartyService { + PartiesInfo parties; + Dictionary> partyData = new Dictionary>(); + + public PartyService() { + parties = XmlUtil.DeserializeXml(XmlUtil.ReadResourceXmlString("parties_info")); + + foreach (PartyInfo party in parties.Parties) { + if (partyData.TryGetValue(party.GameID, out Dictionary? partyDict)) { + partyDict.TryAdd(party.Type, party); + } else { + partyDict = new Dictionary(); + partyData.Add(party.GameID, partyDict); + } + } + } + + public PartyInfo? GetParty(uint gameID, string partyType) { + if (!partyData.TryGetValue(gameID, out Dictionary? partyDict)) return null; + partyDict.TryGetValue(partyType, out PartyInfo? party); + return party; + } + + public string? GetLocation(PartyInfo party) { + parties.LocationIcons.TryGetValue(party.Location, out string? value); + return value; + } +} \ No newline at end of file diff --git a/src/Services/XmlDataService.cs b/src/Services/XmlDataService.cs index e5c169f..6e626d8 100644 --- a/src/Services/XmlDataService.cs +++ b/src/Services/XmlDataService.cs @@ -8,6 +8,8 @@ namespace sodoff.Services; public class XmlDataService { Dictionary displayNames = new(); Dictionary worlds_id = new(); + Dictionary> partyData = new(); + Dictionary partyLocations; public XmlDataService(IOptions config) { if (!config.Value.LoadNonSoDData) @@ -23,6 +25,20 @@ public class XmlDataService { foreach (var w in worlds) { worlds_id[w.Scene] = w.ID; } + + var parties = XmlUtil.DeserializeXml(XmlUtil.ReadResourceXmlString("parties_info")); + foreach (PartyInfo party in parties.Parties) { + if (partyData.TryGetValue(party.GameID, out Dictionary? partyDict)) { + partyDict.TryAdd(party.Type, party); + } else { + partyDict = new Dictionary { + {party.Type, party} + }; + partyData.Add(party.GameID, partyDict); + } + } + + partyLocations = parties.LocationIcons; } public string GetDisplayName(int firstNameID, int secondNameID, int thirdNameID) { @@ -34,4 +50,15 @@ public class XmlDataService { return worlds_id[mapName]; return 0; } + + public PartyInfo? GetParty(uint gameID, string partyType) { + if (!partyData.TryGetValue(gameID, out Dictionary? partyDict)) return null; + partyDict.TryGetValue(partyType, out PartyInfo? party); + return party; + } + + public string? GetPartyLocation(PartyInfo party) { + partyLocations.TryGetValue(party.Location, out string? value); + return value; + } } diff --git a/src/sodoff.csproj b/src/sodoff.csproj index 4e30ed9..cc1e9bf 100644 --- a/src/sodoff.csproj +++ b/src/sodoff.csproj @@ -146,6 +146,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest