From 4f532cb02d1991fc56d523f5768c4e26e3019de8 Mon Sep 17 00:00:00 2001 From: JumpSuit <26616362+Jump-Suit@users.noreply.github.com> Date: Sun, 6 Oct 2024 17:46:55 -0500 Subject: [PATCH 01/16] Begin Blaze support --- .../WebAPIService/CCPGames/Dust514Class.cs | 207 +++++++++++ .../CCPGames/Helpers/NPTicketSample.cs | 134 +++++++ .../WebAPIService/HTS/HTSClass.cs | 2 +- .../HTS/Helpers/NPTicketSample.cs | 2 +- .../WebAPIService/WebAPIService.csproj | 1 + .../MultiSocks/Blaze/BlazeClass.cs | 24 +- .../Blaze/Components/Auth/AuthComponent.cs | 107 ++++++ .../Redirector/RedirectorComponent.cs | 80 ++++ .../Blaze/Components/Util/UtilComponent.cs | 330 +++++++++++++++++ .../Blaze/Redirector/RedirectorComponent.cs | 3 +- .../VulnerableCertificateGenerator.cs | 4 +- .../static/EA/ME3_CONFIG/ME3DATA - Copy.txt | 16 + .../static/EA/ME3_CONFIG/ME3_DATA.txt | 16 + .../static/EA/ME3_CONFIG/ME3_DIME.txt | 46 +++ .../static/EA/ME3_CONFIG/ME3_ENT.txt | 343 ++++++++++++++++++ .../static/EA/ME3_CONFIG/ME3_MSG.txt | 21 ++ WebServers/HTTPServer/HttpProcessor.cs | 31 +- WebServers/HTTPServer/Program.cs | 2 +- 18 files changed, 1358 insertions(+), 11 deletions(-) create mode 100644 BackendServices/AuxiliaryServices/WebAPIService/CCPGames/Dust514Class.cs create mode 100644 BackendServices/AuxiliaryServices/WebAPIService/CCPGames/Helpers/NPTicketSample.cs create mode 100644 SpecializedServers/MultiSocks/Blaze/Components/Auth/AuthComponent.cs create mode 100644 SpecializedServers/MultiSocks/Blaze/Components/Redirector/RedirectorComponent.cs create mode 100644 SpecializedServers/MultiSocks/Blaze/Components/Util/UtilComponent.cs create mode 100644 SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/ME3DATA - Copy.txt create mode 100644 SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/ME3_DATA.txt create mode 100644 SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/ME3_DIME.txt create mode 100644 SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/ME3_ENT.txt create mode 100644 SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/ME3_MSG.txt diff --git a/BackendServices/AuxiliaryServices/WebAPIService/CCPGames/Dust514Class.cs b/BackendServices/AuxiliaryServices/WebAPIService/CCPGames/Dust514Class.cs new file mode 100644 index 000000000..f6ae202d7 --- /dev/null +++ b/BackendServices/AuxiliaryServices/WebAPIService/CCPGames/Dust514Class.cs @@ -0,0 +1,207 @@ +using CustomLogger; +using NetworkLibrary.HTTP; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; + +namespace WebAPIService.CCPGames +{ + public class Dust514Class : IDisposable + { + private string workpath; + private string absolutepath; + private string method; + private bool disposedValue; + + public Dust514Class(string method, string absolutepath, string workpath) + { + this.absolutepath = absolutepath; + this.workpath = workpath; + this.method = method; + } + + public string ProcessRequest(byte[] PostData, string ContentType, List> headers, bool https) + { + if (string.IsNullOrEmpty(absolutepath)) + return null; + + //string GlobalState.charaId = string.Empty; + //bool isLoggedIn = false; + + switch (method) + { + case "GET": + switch (absolutepath) + { + case "/dust/server/": + return @"{""serverVersion"":""1.0.0.7"", + ""crestEndpoint"":{ + ""href"":""http://dust514.online:26004/crest/""}, + ""sentryDSN"":"""", + ""edenTime"":"""", + ""userCount"":0, + ""authEndpoint"":{ + ""username"":""http://dust514.online:26004/dust/auth/""}, + ""status"":""OPEN""}"; + case "/crest/": + + if(GlobalState.isLoggedIn == true) { + return @"{""character"":{""name"":""Wrecker 39"",""href"":""http://dust514.online:26004/character/2100000000/"",""id"":2100000000,""contacts"":{""href"":""""},""private"":{""href"":""""},""mercenary"":{""href"":""""},""corporation"":{""href"":"""",""id"":0,""name"":""""},""corporationMember"":{""href"":""""},""mail"":{""href"":""""},""description"":"""",""gender"":false,""race"":{""id"":0,""name"":"""",""icon"":{""href"":""""},""description"":"""",""href"":""""},""bloodLine"":{""href"":"""",""id"":0},""portrait"":{""id"":0},""skills"":{""href"":""""},""notifications"":{""href"":""""},""channels"":{""href"":""""},""npeSettings"":{""href"":""""}},""marketGroups"":{""href"":""http://dust514.online:26004/market/groups/350001/""}}"; + } else + { + return @"{""user"": + {""href"":""http://dust514.online:26004/user/""}, + ""pathToGame"":{""href"":""http://dust514.online:26004/document_map/""}, + ""contentStreaming"":{""href"":""http://dust514.online:26004/content_streaming/manifest/""}, + ""races"":{""href"":""http://dust514.online:26004/static_data/races/""}, + ""bloodlines"":{""href"":""http://dust514.online:26004/static_data/bloodlines/""}, + ""specialties"":{""href"":""http://dust514.online:26004/static_data/specialties/""}, + ""portraits"":{""href"":""http://dust514.online:26004/static_data/portraits/""}, + ""mercenaries"":{""href"":""http://dust514.online:26004/mercenaries/""}, + ""battleQueues"":{""href"":""http://dust514.online:26004/battle/queues/""}, + ""battles"":{""href"":""http://dust514.online:26004/battle/battles/""}, + ""squads"":{""href"":""http://dust514.online:26004/squads/""}}"; + } + case "/user/": + return @"{""notifications"":{""href"":""http://dust514.online:26004/notifications/""}, + ""mercenaries"":{""href"":""http://dust514.online:26004/mercenaries/""}}"; + case "/document_map/": + return @"{""ageconfirmation"":{""href"":""http://dust514.online:26004/document_map/ageconfirmation/""}, + ""eula"":{""href"":""http://dust514.online:26004/document_map/eula/""}, + ""nda"":{""href"":""http://dust514.online:26004/document_map/nda/""}, + ""servernotavailable"":{""href"":""http://dust514.online:26004/document_map/servernotavailable/""}, + ""patchnotes"":{""href"":""http://dust514.online:26004/document_map/patchnotes/""}}"; + case "/document_map/eula/": + return @"{""text"":""Fuck a EULA""}"; + case "/document_map/patchnotes/": + return @"{""text"":""Patch notes not available""}"; + case "/document_map/ageconfirmation/": + //return @"{""title"":""dcrest error"",""message"":""not found"",""type"":""dcrest: 404""}"; + return @"{""text"":""Age Confirmation Not Implemented""}"; + case "/content_streaming/manifest/": + return @"{""live"":[{""bundle"":""bundles/localbundle"",""p"":0}]}"; + case "/bundles/localbundle": + return @"[{""url"":""HQMYB6TYSRH44WKXB4MOQ6ITACANZSIZ.PSARC"",""platform"":""PS3-Shipping"",""size"":300917324}, + {""url"":""MAJHNCJMZ6GWSFFDIK6NX7YFSXSLFIXE.PSARC"",""platform"":""PS3-Shipping"",""size"":138966717}, + {""url"":""OCIHWOESL5RHX6W3UK422BWSYJ7ZY7MK.PSARC"",""platform"":""PS3-Shipping"",""size"":974385094}, + {""url"":""OO26UJNUQFD4V3HM3P64AJJXBGPBXU5U.PSARC"",""platform"":""PS3-Shipping"",""size"":13450241}]"; + case "/mercenaries/": + return @"{""items"":[{""favoriteFitting"":"""",""bloodline"":{""href"":""http://dust514.online:26004/bloodline/2/"",""id"":2},""gender"":1,""self"":"""",""skillPoints"":500000,""private"":{""href"":""http://dust514.online:26004/character/2100000000/mercenary/private/""},""corporation"":{""name"":""A Corporation"",""memberFor"":""Member Forever""},""character"":{""name"":""Wrecker 39"",""href"":""http://dust514.online:26004/character/2100000000/"",""id"":2100000000,""contacts"":{""href"":""http://dust514.online:26004/character/2100000000/contacts/""},""private"":{""href"":""http://dust514.online:26004/character/2100000000/private/""},""mercenary"":{""href"":""http://dust514.online:26004/mercenary/2100000000/""},""corporation"":{""href"":""http://dust514.online:26004/corporation/1/"",""id"":1,""name"":""""},""corporationMember"":{""href"":""http://dust514.online:26004/corporation/1/member/2100000000""},""mail"":{""href"":""http://dust514.online:26004/character/2100000000/mail/""},""description"":""fuckoff"",""gender"":true,""race"":{""id"":1,""name"":""Caldari"",""icon"":{""href"":""http://dust514.online:26004/race/1/icon/""},""description"":""Founded on the tenets of patriotism and hard work that carried its ancestors through hardships on an inhospitable homeworld, the Caldari State is today a corporate dictatorship, led by rulers who are determined to see it return to the meritocratic ideals of old. Ruthless and efficient in the boardroom as well as on the battlefield, the Caldari are living emblems of strength, persistence, and dignity."",""href"":""http://dust514.online:26004/race/1/""},""bloodLine"":{""href"":"""",""id"":0},""portrait"":{""id"":0},""skills"":{""href"":""""},""notifications"":{""href"":""http://dust514.online:26004/character/2100000000/notifications/""},""channels"":{""href"":""http://dust514.online:26004/character/2100000000/channels/""},""npeSettings"":{""href"":""http://dust514.online:26004/character/2100000000/mercenary/npe_settings/""}},""portrait"":{""id"":1},""wealth"":{""isk"":250000},""passiveSkillGain"":{""status"":false,""self"":{""href"":""http://dust514.online:26004""}},""npeState"":1}]}"; + case "/static_data/races/": + return @"{""items"":[{""name"":""Caldari"",""description"":""Founded on the tenets of patriotism and hard work that carried its ancestors through hardships on an inhospitable homeworld, the Caldari State is today a corporate dictatorship, led by rulers who are determined to see it return to the meritocratic ideals of old. Ruthless and efficient in the boardroom as well as on the battlefield, the Caldari are living emblems of strength, persistence, and dignity."",""href"":""https://dust514.online/static_data/race/1/"",""icon"":{""href"":""icon_race_caldari""}},{""name"":""Minmatar"",""description"":""Once a thriving tribal civilization, the Minmatar were enslaved by the Amarr Empire for more than 700 years until a massive rebellion freed most, but not all, of those held in servitude. The Minmatar people today are resilient, ingenious, and hard-working. Many of them believe that democracy, though it has served them well for a long time, can never restore what was taken from them so long ago. For this reason they have formed a government truly reflective of their tribal roots. They will forever resent the Amarrians, and yearn for the days before the Empire"",""href"":""https://dust514.online/static_data/race/2/"",""icon"":{""href"":""icon_race_minmatar""}},{""name"":""Amarr"",""description"":""The Amarr Empire is the largest and oldest of the four empires. Ruled by a mighty God-Emperor, this vast theocratic society is supported by a broad foundation of slave labor. Amarrian citizens tend to be highly educated and fervent individuals, and as a culture Amarr adheres to the basic tenet that what others call slavery is in fact one step on a indentured person’s spiritual path toward fully embracing their faith. Despite several setbacks in recent history, the Empire remains arguably the most stable and militarily powerful nation-state in New Eden"",""href"":""https://dust514.online/static_data/race/4/"",""icon"":{""href"":""icon_race_amarr""}},{""name"":""Gallente"",""description"":""Champions of liberty and defenders of the downtrodden, the Gallente play host to the only true democracy in New Eden. Some of the most progressive leaders, scientists, and businessmen of the era have emerged from its diverse peoples. A pioneer of artificial intelligence, the Federation relies heavily on drones and other automated systems. This is not to detract from the skill of their pilots, though: the Gallente Federation is known for producing some of the best and bravest the universe has to offer."",""href"":""https://dust514.online/static_data/race/8/"",""icon"":{""href"":""icon_race_gallente""}}]}"; + + default: + break; + } + break; + case "PUT": + switch (absolutepath) + { + case "/": + return @"{""configuration"":{""href"":""http://dust514.online:26004/cfg/""}}"; + + } + break; + case "POST": + switch (absolutepath) + { + case "/dust/auth/": + + string pattern = @"character=(\d+)"; + string authData = Encoding.UTF8.GetString(PostData); + Match match = Regex.Match(authData, pattern); + + if (match.Success) + { + GlobalState.charaId = match.Groups[1].Value; + LoggerAccessor.LogWarn("Character ID: " + GlobalState.charaId); + GlobalState.isLoggedIn = true; + } + else + { + LoggerAccessor.LogWarn("Character ID not found."); + GlobalState.isLoggedIn = false; + } + + return "{\"access_token\":\"8d00eee7-0405-5b40-de54-218d79cc17ce\",\"refresh_token\":\"8d00eee7-0405-5b40-de54-218d79cc17ce\",\"token_type\":\"dust\"}"; + } + break; + default: + break; + } + + if (absolutepath.Equals($"character/{GlobalState.charaId}/private/")) + { + return $"{{\"location\":{{\"href\":\"http://dust514.online:26004/location/60014943/\"}},\"fittings\":{{\"href\":\"http://dust514.online:26004/character/{GlobalState.charaId}/mercenary/fittings/\"}}"; + } + else if (absolutepath.Equals($"character/{GlobalState.charaId}/fulfillments/")) + { + return $"{{\"items\":\"\"}}"; + } + else if (absolutepath.Equals($"character/{GlobalState.charaId}/mercenary/")) + { + return $"{{\"name\":\"Wrecker 39\",\"href\":\"http://dust514.online:26004/character/{GlobalState.charaId}/\",\"id\":{GlobalState.charaId},\"contacts\":{{\"href\":\"http://dust514.online:26004/character/{GlobalState.charaId}/contacts/\"}},\"private\":{{\"href\":\"http://dust514.online:26004/character/{GlobalState.charaId}/private/\"}},\"mercenary\":{{\"href\":\"http://dust514.online:26004/character/{GlobalState.charaId}/mercenary/\"}},\"corporation\":{{\"href\":\"http://dust514.online:26004/corporation/1000134/\",\"id\":1,\"name\":\"A Corporation\"}},\"corporationMember\":{{\"href\":\"http://dust514.online:26004/corporation/1/member/{GlobalState.charaId}/\"}},\"mail\":{{\"href\":\"http://dust514.online:26004/character/{GlobalState.charaId}/mail/\"}},\"description\":\"\",\"gender\":true,\"race\":{{\"id\":1,\"name\":\"\",\"icon\":{{\"href\":\"http://dust514.online:26004/race/1/icon/\"}},\"description\":\"\",\"href\":\"http://dust514.online:26004/race/1/\"}},\"bloodLine\":{{\"href\":\"http://dust514.online:26004/bloodline/2\",\"id\":2}},\"portrait\":{{\"id\":1}},\"skills\":{{\"href\":\"http://dust514.online:26004/character/{GlobalState.charaId}/mercenary/skills/\"}},\"notifications\":{{\"href\":\"http://dust514.online:26004/character/{GlobalState.charaId}/notifications/\"}},\"channels\":{{\"href\":\"http://dust514.online:26004/character/{GlobalState.charaId}/channels/\"}},\"npeSettings\":{{\"href\":\"http://dust514.online:26004/character/{GlobalState.charaId}/mercenary/npe_settings/\"}}"; + } + else if (absolutepath.Equals($"character/{GlobalState.charaId}/")) + { + + //Get Player character + return $"{{\"name\":\"Wrecker 39\",\"href\":\"http://dust514.online:26004/character/{GlobalState.charaId}/\",\"id\":{GlobalState.charaId}," + + $"\"contacts\":{{\"href\":\"http://dust514.online:26004/character/{GlobalState.charaId}/contacts/\"}}," + + $"\"private\":{{\"href\":\"http://dust514.online:26004/character/{GlobalState.charaId}/private/\"}}," + + $"\"mercenary\":{{\"href\":\"http://dust514.online:26004/character/{GlobalState.charaId}/mercenary/\"}}," + + $"\"corporation\":{{\"href\":\"http://dust514.online:26004/corporation/1000134/\",\"id\":1,\"name\":\"A Corporation\"}}," + + $"\"corporationMember\":{{\"href\":\"http://dust514.online:26004/corporation/1/member/{GlobalState.charaId}/\"}}," + + $"\"mail\":{{\"href\":\"http://dust514.online:26004/character/{GlobalState.charaId}/mail/\"}},\"description\":\"\",\"gender\":true," + + $"\"race\":{{\"id\":1,\"name\":\"\"," + + $"\"icon\":{{\"href\":\"http://dust514.online:26004/race/1/icon/\"}},\"description\":\"\"," + + $"\"href\":\"http://dust514.online:26004/race/1/\"}}," + + $"\"bloodLine\":{{\"href\":\"http://dust514.online:26004/bloodline/2\",\"id\":2}}," + + $"\"portrait\":{{\"id\":1}},\"skills\":{{\"href\":\"http://dust514.online:26004/character/{GlobalState.charaId}/mercenary/skills/\"}}," + + $"\"notifications\":{{\"href\":\"http://dust514.online:26004/character/{GlobalState.charaId}/notifications/\"}}," + + $"\"channels\":{{\"href\":\"http://dust514.online:26004/character/{GlobalState.charaId}/channels/\"}}," + + $"\"npeSettings\":{{\"href\":\"http://dust514.online:26004/character/{GlobalState.charaId}/mercenary/npe_settings/\"}}"; + } + + return null; + } + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + absolutepath = string.Empty; + method = string.Empty; + } + + // TODO: libérer les ressources non managées (objets non managés) et substituer le finaliseur + // TODO: affecter aux grands champs une valeur null + disposedValue = true; + } + } + + // // TODO: substituer le finaliseur uniquement si 'Dispose(bool disposing)' a du code pour libérer les ressources non managées + // ~HELLFIREClass() + // { + // // Ne changez pas ce code. Placez le code de nettoyage dans la méthode 'Dispose(bool disposing)' + // Dispose(disposing: false); + // } + + public void Dispose() + { + // Ne changez pas ce code. Placez le code de nettoyage dans la méthode 'Dispose(bool disposing)' + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + } + + public static class GlobalState + { + public static string charaId { get; set; } + public static bool isLoggedIn { get; set; } = false; + } +} diff --git a/BackendServices/AuxiliaryServices/WebAPIService/CCPGames/Helpers/NPTicketSample.cs b/BackendServices/AuxiliaryServices/WebAPIService/CCPGames/Helpers/NPTicketSample.cs new file mode 100644 index 000000000..f67030374 --- /dev/null +++ b/BackendServices/AuxiliaryServices/WebAPIService/CCPGames/Helpers/NPTicketSample.cs @@ -0,0 +1,134 @@ +using CustomLogger; +using HttpMultipartParser; +using System.Text; +using System.IO; +using System; +using NetworkLibrary.Extension; +using HashLib; + +namespace WebAPIService.HTS.Helpers +{ + public class MyResistanceEula + { + public static string RequestNPTicket(byte[] PostData, string boundary) + { + string userid = string.Empty; + string sessionid = string.Empty; + string resultString = string.Empty; + string region = string.Empty; + byte[] ticketData = null; + + if (PostData != null) + { + using (MemoryStream copyStream = new MemoryStream(PostData)) + { + foreach (var file in MultipartFormDataParser.Parse(copyStream, boundary).Files) + { + using (Stream filedata = file.Data) + { + filedata.Position = 0; + + // Find the number of bytes in the stream + int contentLength = (int)filedata.Length; + + // Create a byte array + byte[] buffer = new byte[contentLength]; + + // Read the contents of the memory stream into the byte array + filedata.Read(buffer, 0, contentLength); + + if (file.FileName == "ticket.bin") + ticketData = buffer; + + filedata.Flush(); + } + } + + copyStream.Flush(); + } + } + + if (ticketData != null) + { + #region Region + // Extract part of the byte array from the specific index + byte[] ticketRegion = new byte[] { 0x00, 0x00, 0x00, 0x00 }; + Array.Copy(ticketData, 0x78, ticketRegion, 0, 4); + #endregion + + #region Domain + // Extract part of the byte array from the specific index + byte[] ticketDomain = new byte[] { 0x00, 0x00, 0x00, 0x00 }; + Array.Copy(ticketData, 0x80, ticketDomain, 0, 4); + #endregion + + #region ServiceId + byte serviceIdLen = (byte)ticketData.GetValue(0x87); + // Extract part of the byte array from the specific index + byte[] servId = new byte[serviceIdLen]; + Array.Copy(ticketData, 0x88, servId, 0, serviceIdLen); + #endregion + + // Extract the desired portion of the binary data + byte[] userOnlineId = new byte[0x63 - 0x54 + 1]; + + // Copy it + Array.Copy(ticketData, 0x54, userOnlineId, 0, userOnlineId.Length); + + // Convert 0x00 bytes to 0x20 so we pad as space. + for (int i = 0; i < userOnlineId.Length; i++) + { + if (userOnlineId[i] == 0x00) + userOnlineId[i] = 0x20; + } + + if (OtherExtensions.FindBytePattern(ticketData, new byte[] { 0x52, 0x50, 0x43, 0x4E }, 184) != -1) + { + LoggerAccessor.LogInfo($"[HTS] : User {Encoding.ASCII.GetString(userOnlineId).Replace("H", string.Empty)} logged in and is on RPCN"); + + // Convert the modified data to a string + resultString = Encoding.ASCII.GetString(userOnlineId) + "RPCN"; + + // Calculate the MD5 hash of the result + string hash = NetHasher.ComputeMD5String(Encoding.ASCII.GetBytes(resultString + "HtTeStSamPLe@$!")); + + // Trim the hash to a specific length + hash = hash.Substring(0, 10); + + // Append the trimmed hash to the result + resultString += hash; + } + else + { + LoggerAccessor.LogInfo($"[HTS] : {Encoding.ASCII.GetString(userOnlineId).Replace("H", string.Empty)} logged in and is on PSN"); + + // Convert the modified data to a string + resultString = Encoding.ASCII.GetString(userOnlineId); + + // Calculate the MD5 hash of the result + string hash = NetHasher.ComputeMD5String(Encoding.ASCII.GetBytes(resultString + "HtTeStSamPLe@$!")); + + // Trim the hash to a specific length + hash = hash.Substring(0, 14); + + // Append the trimmed hash to the result + resultString += hash; + } + + return $@" + {Encoding.UTF8.GetString(userOnlineId)} + + + + + {Encoding.UTF8.GetString(servId)} + {Encoding.UTF8.GetString(ticketRegion)} + + + "; + } + + return null; + } + } +} diff --git a/BackendServices/AuxiliaryServices/WebAPIService/HTS/HTSClass.cs b/BackendServices/AuxiliaryServices/WebAPIService/HTS/HTSClass.cs index 4287a7b59..f5ac6ccb8 100644 --- a/BackendServices/AuxiliaryServices/WebAPIService/HTS/HTSClass.cs +++ b/BackendServices/AuxiliaryServices/WebAPIService/HTS/HTSClass.cs @@ -33,7 +33,7 @@ public string ProcessRequest(byte[] PostData, string ContentType, bool https) case "/NPTicketing/get_ticket_data.json": case "/NPTicketing/get_ticket_data_base64.xml": case "/NPTicketing/get_ticket_data_base64.json": - return MyResistanceEula.RequestNPTicket(PostData, HTTPProcessor.ExtractBoundary(ContentType)); + return NPTicketSample.RequestNPTicket(PostData, HTTPProcessor.ExtractBoundary(ContentType)); #endregion default: diff --git a/BackendServices/AuxiliaryServices/WebAPIService/HTS/Helpers/NPTicketSample.cs b/BackendServices/AuxiliaryServices/WebAPIService/HTS/Helpers/NPTicketSample.cs index f67030374..7bca79072 100644 --- a/BackendServices/AuxiliaryServices/WebAPIService/HTS/Helpers/NPTicketSample.cs +++ b/BackendServices/AuxiliaryServices/WebAPIService/HTS/Helpers/NPTicketSample.cs @@ -8,7 +8,7 @@ namespace WebAPIService.HTS.Helpers { - public class MyResistanceEula + public class NPTicketSample { public static string RequestNPTicket(byte[] PostData, string boundary) { diff --git a/BackendServices/AuxiliaryServices/WebAPIService/WebAPIService.csproj b/BackendServices/AuxiliaryServices/WebAPIService/WebAPIService.csproj index e387611f6..17f39613c 100644 --- a/BackendServices/AuxiliaryServices/WebAPIService/WebAPIService.csproj +++ b/BackendServices/AuxiliaryServices/WebAPIService/WebAPIService.csproj @@ -14,6 +14,7 @@ + diff --git a/SpecializedServers/MultiSocks/Blaze/BlazeClass.cs b/SpecializedServers/MultiSocks/Blaze/BlazeClass.cs index 5ae4ad463..a380c0006 100644 --- a/SpecializedServers/MultiSocks/Blaze/BlazeClass.cs +++ b/SpecializedServers/MultiSocks/Blaze/BlazeClass.cs @@ -1,7 +1,10 @@ using Blaze3SDK; +using Blaze3SDK.Blaze; using BlazeCommon; using CustomLogger; -using MultiSocks.Blaze.Redirector; +using MultiSocks.Blaze.Components.Redirector; +using MultiSocks.Blaze.Components.Util; +using MultiSocks.Blaze.Util; using MultiSocks.ProtoSSL; using System.Net; @@ -12,6 +15,7 @@ public class BlazeClass : IDisposable private bool disposedValue; private BlazeServer redirector; + private BlazeServer mainBlaze; private VulnerableCertificateGenerator? SSLCache = new(); public BlazeClass(CancellationToken cancellationToken) @@ -20,20 +24,31 @@ public BlazeClass(CancellationToken cancellationToken) string domain = "gosredirector.ea.com"; // Create Blaze Redirector server - redirector = Blaze3.CreateBlazeServer(domain, new IPEndPoint(IPAddress.Any, 42127), SSLCache.GetVulnerableCustomEaCert(domain, "fesl@ea.com").Item3); + redirector = Blaze3.CreateBlazeServer(domain, new IPEndPoint(IPAddress.Any, 42127), SSLCache.GetVulnerableCustomEaCert(domain, "fesl@ea.com", "Global Online Studio").Item3); + // Create Main Blaze server + mainBlaze = Blaze3.CreateBlazeServer(domain, new IPEndPoint(IPAddress.Any, 33152), SSLCache.GetVulnerableCustomEaCert(domain, "fesl@ea.com").Item3, false); redirector.AddComponent(); + mainBlaze.AddComponent(); + mainBlaze.AddComponent(); - _ = StartServer(); + _ = StartRedirectorServer(); + _ = StartMainBlazeServer(); LoggerAccessor.LogInfo("Blaze Servers initiated..."); } - private async Task StartServer() + private async Task StartRedirectorServer() { //Start it! await redirector.Start(-1).ConfigureAwait(false); } + private async Task StartMainBlazeServer() + { + //Start it! + await mainBlaze.Start(-1).ConfigureAwait(false); + } + protected virtual void Dispose(bool disposing) { if (!disposedValue) @@ -41,6 +56,7 @@ protected virtual void Dispose(bool disposing) if (disposing) { redirector.Stop(); + mainBlaze.Stop(); LoggerAccessor.LogWarn("Blaze Servers stopped..."); } diff --git a/SpecializedServers/MultiSocks/Blaze/Components/Auth/AuthComponent.cs b/SpecializedServers/MultiSocks/Blaze/Components/Auth/AuthComponent.cs new file mode 100644 index 000000000..307da40ca --- /dev/null +++ b/SpecializedServers/MultiSocks/Blaze/Components/Auth/AuthComponent.cs @@ -0,0 +1,107 @@ +using Blaze3SDK; +using Blaze3SDK.Blaze.Authentication; +using Blaze3SDK.Blaze.Util; +using Blaze3SDK.Components; +using BlazeCommon; +using CustomLogger; +using MultiSocks.Utils; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MultiSocks.Blaze.Util +{ + internal class AuthComponent : AuthenticationComponentBase.Server + { + /// + /// You only need to override the base method to handle new requests. + /// If the request type or/and response type is NullStruct, you can change the request/response types in the Component Base. + /// + public override Task Ps3LoginAsync(PS3LoginRequest request, BlazeRpcContext context) + { + //if needded access underlying connection which issued the request and other stuff + ProtoFireConnection connection = context.Connection; + + //manually displaying some data + LoggerAccessor.LogInfo($"[Blaze] - Auth: Connection Id : {connection.ID}"); + LoggerAccessor.LogInfo($"[Blaze] - Auth: Email : {request.mEmail}"); + LoggerAccessor.LogInfo($"[Blaze] - Auth: Client Type : {request.mPS3Ticket}"); + + /* + //if something is wrong with request data - thrown an BlazeRpcException with error code and error data, which will be sent to client (in debug environment disable breaking on this exception) + if (request.mName == "someValueHere") + { + throw new BlazeRpcException(Blaze3RpcError.REDIRECTOR_UNKNOWN_SERVICE_NAME, new ServerInstanceError() + { + mMessages = new List() { + "Unknown service name" + } + }); + } + */ + + + string ip = MultiSocksServerConfiguration.UsePublicIPAddress ? NetworkLibrary.TCP_IP.IPUtils.GetPublicIPAddress() : NetworkLibrary.TCP_IP.IPUtils.GetLocalIPAddress().ToString(); + uint unixTimeStamp = (UInt32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; + + + + ConsoleLoginResponse consoleLoginResponse = new ConsoleLoginResponse() + { + mCanAgeUp = false, + mIsOfLegalContactAge = true, + mLegalDocHost = "", + mNeedsLegalDoc = false, + mPrivacyPolicyUri = "", + mSessionInfo = new SessionInfo() + { + mBlazeUserId = 1, + mEmail = request.mEmail, + mIsFirstLogin = true, + mLastLoginDateTime = unixTimeStamp, + mPersonaDetails = new PersonaDetails() + { + mDisplayName = "Dust514JumpDev", + mExtId = 1, + mExtType = ExternalRefType.BLAZE_EXTERNAL_REF_TYPE_PS3, + mLastAuthenticated = unixTimeStamp, + mPersonaId = 1, + mStatus = PersonaStatus.ACTIVE, + }, + mSessionKey = "11229301_9b171d92cc562b293e602ee8325612e7", + mUserId = 1, + }, + mTosHost = "", + mTermsOfServiceUri = "", + mTosUri = "", + + }; + + + //return the response + return Task.FromResult(consoleLoginResponse); + } + + + + + /// + /// You only need to override the base method to handle new requests. + /// If the request type or/and response type is NullStruct, you can change the request/response types in the Component Base. + /// + public override Task LogoutAsync(NullStruct request, BlazeRpcContext context) + { + //if needded access underlying connection which issued the request and other stuff + ProtoFireConnection connection = context.Connection; + + //manually displaying some data + LoggerAccessor.LogInfo($"[Blaze] - Auth: Logout Connection Id : {connection.ID}"); + + + //return the response + return null; + } + } +} diff --git a/SpecializedServers/MultiSocks/Blaze/Components/Redirector/RedirectorComponent.cs b/SpecializedServers/MultiSocks/Blaze/Components/Redirector/RedirectorComponent.cs new file mode 100644 index 000000000..b90302116 --- /dev/null +++ b/SpecializedServers/MultiSocks/Blaze/Components/Redirector/RedirectorComponent.cs @@ -0,0 +1,80 @@ +using Blaze3SDK; +using Blaze3SDK.Blaze.Redirector; +using Blaze3SDK.Components; +using BlazeCommon; +using CustomLogger; +using MultiSocks.Utils; + +namespace MultiSocks.Blaze.Components.Redirector +{ + internal class RedirectorComponent : RedirectorComponentBase.Server + { + /// + /// You only need to override the base method to handle new requests. + /// If the request type or/and response type is NullStruct, you can change the request/response types in the Component Base. + /// + public override Task GetServerInstanceAsync(ServerInstanceRequest request, BlazeRpcContext context) + { + //if needded access underlying connection which issued the request and other stuff + ProtoFireConnection connection = context.Connection; + + //manually displaying some data + LoggerAccessor.LogInfo($"[Blaze] - Redirector: Connection Id : {connection.ID}"); + LoggerAccessor.LogInfo($"[Blaze] - Redirector: Service Name : {request.mName}"); + LoggerAccessor.LogInfo($"[Blaze] - Redirector: Client Type : {request.mClientType}"); + LoggerAccessor.LogInfo($"[Blaze] - Redirector: Client Platform : {request.mPlatform}"); + + //if something is wrong with request data - thrown an BlazeRpcException with error code and error data, which will be sent to client (in debug environment disable breaking on this exception) + if (request.mName == "someValueHere") + { + throw new BlazeRpcException(Blaze3RpcError.REDIRECTOR_UNKNOWN_SERVICE_NAME, new ServerInstanceError() + { + mMessages = new List() { + "Unknown service name" + } + }); + } + + //Connection details + bool secure = false; //insecure + string ip = "127.0.0.1"; + ushort port = 33152; + + ServerInstanceInfo responseData = new() + { + //this is an union type, so we specify only one of the values + mAddress = new ServerAddress() + { + IpAddress = new IpAddress() + { + mHostname = ip, + mIp = NetworkUtils.GetIPAddressAsUInt(ip), + mPort = port + }, + }, + + //optionally address remaps can be specified + mAddressRemaps = new List() + { + + }, + + //optionally server messages can be specified + mMessages = new List() { + //"Hello, from Multiserver!" + }, + + //optionally name remaps can be specified + mNameRemaps = new List() + { + + }, + mSecure = secure, + mDefaultDnsAddress = 0 + }; + + //return the response + return Task.FromResult(responseData); + } + } +} diff --git a/SpecializedServers/MultiSocks/Blaze/Components/Util/UtilComponent.cs b/SpecializedServers/MultiSocks/Blaze/Components/Util/UtilComponent.cs new file mode 100644 index 000000000..b35509626 --- /dev/null +++ b/SpecializedServers/MultiSocks/Blaze/Components/Util/UtilComponent.cs @@ -0,0 +1,330 @@ +using Blaze3SDK; +using Blaze3SDK.Blaze; +using Blaze3SDK.Blaze.Util; +using Blaze3SDK.Components; +using BlazeCommon; +using CustomLogger; +using MultiSocks.Aries.Messages; +using MultiSocks.Utils; +using Org.BouncyCastle.Asn1.Ocsp; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MultiSocks.Blaze.Components.Util +{ + internal class UtilComponent : UtilComponentBase.Server + { + /// + /// You only need to override the base method to handle new requests. + /// If the request type or/and response type is NullStruct, you can change the request/response types in the Component Base. + /// + public override Task PreAuthAsync(PreAuthRequest request, BlazeRpcContext context) + { + //if needded access underlying connection which issued the request and other stuff + ProtoFireConnection connection = context.Connection; + + //manually displaying some data + LoggerAccessor.LogInfo($"[Blaze] - Util: Connection Id : {connection.ID}"); + LoggerAccessor.LogInfo($"[Blaze] - Util: Locale : {request.mClientData.mLocale}"); + LoggerAccessor.LogInfo($"[Blaze] - Util: Client Type : {request.mClientData.mClientType}"); + LoggerAccessor.LogInfo($"[Blaze] - Util: Client Platform : {request.mClientInfo.mPlatform}"); + LoggerAccessor.LogInfo($"[Blaze] - Util: Client mEnvironment : {request.mClientInfo.mEnvironment}"); + + /* + //if something is wrong with request data - thrown an BlazeRpcException with error code and error data, which will be sent to client (in debug environment disable breaking on this exception) + if (request.mName == "someValueHere") + { + throw new BlazeRpcException(Blaze3RpcError.REDIRECTOR_UNKNOWN_SERVICE_NAME, new ServerInstanceError() + { + mMessages = new List() { + "Unknown service name" + } + }); + } + */ + + + var fetchConfig = new SortedDictionary(); + fetchConfig.Add("pingPeriod", "15s"); + fetchConfig.Add("voipHeadsetUpdateRate", "1000"); + fetchConfig.Add("xlspConnectionIdleTimeout", "300"); + + QosPingSiteInfo qosPingSiteInfoSJC = new QosPingSiteInfo() + { + mAddress = "gossjcprod-qos01.ea.com", + mPort = 17502, + mSiteName = "prod-sjc", + }; + + QosPingSiteInfo qosPingSiteInfoIAD = new QosPingSiteInfo() + { + mAddress = "gosiadprod-qos01.ea.com", + mPort = 17502, + mSiteName = "bio-iad-prod-shared", + }; + QosPingSiteInfo qosPingSiteInfolhr = new QosPingSiteInfo() + { + mAddress = "gosgvaprod-qos01.ea.com", + mPort = 17502, + mSiteName = "bio-dub-prod-shared", + }; + + var pingSiteInfoByAliasNames = new SortedDictionary(); + + pingSiteInfoByAliasNames.Add("ea-sjc", qosPingSiteInfoSJC); + pingSiteInfoByAliasNames.Add("rs-iad", qosPingSiteInfoIAD); + pingSiteInfoByAliasNames.Add("rs-lhr", qosPingSiteInfolhr); + + + + PreAuthResponse responseData = new() + { + mAnonymousChildAccountsEnabled = false, + mAuthenticationSource = "303107", + + //ushort list + mComponentIds = new List() + { + 1, + 4, + 7, + 9, + 15, + 25, + 28, + 2000, + 30720, + 30721, + 30722, + 30723, + 30725, + 30726, + 63490 + }, + mConfig = new FetchConfigResponse() + { + mConfig = fetchConfig, + }, + mInstanceName = "masseffect-3-ps3", + mLegalDocGameIdentifier = "GameID", + mParentalConsentEntitlementGroupName = "PCEGN", + mParentalConsentEntitlementTag = "PCETAG", + mPersonaNamespace = "cem_ea_id", + mPlatform = "PS3", + mQosSettings = new() + { + mBandwidthPingSiteInfo = new QosPingSiteInfo() { + mAddress = "gossjcprod-qos01.ea.com", + mPort = 17502, + mSiteName = "prod-sjc", + }, + mNumLatencyProbes = 10, + mPingSiteInfoByAliasMap = pingSiteInfoByAliasNames, + mServiceId = 1 + }, + mServerVersion = "Blaze 3.15.08.0 (CL# 750727)", // Crysis 3 Blaze ver + mUnderageSupported = false, + + }; + + //return the response + return Task.FromResult(responseData); + } + + public override Task PostAuthAsync(NullStruct request, BlazeRpcContext context) + { + + byte[] skey = { 0x5E, 0x8A, 0xCB, 0xDD, 0xF8, 0xEC, 0xC1, 0x95, 0x98, 0x99, 0xF9, 0x94, 0xC0, 0xAD, 0xEE, 0xFC, 0xCE, 0xA4, 0x87, 0xDE, 0x8A, 0xA6, 0xCE, 0xDC, 0xB0, 0xEE, 0xE8, 0xE5, 0xB3, 0xF5, 0xAD, 0x9A, 0xB2, 0xE5, 0xE4, 0xB1, 0x99, 0x86, 0xC7, 0x8E, 0x9B, 0xB0, 0xF4, 0xC0, 0x81, 0xA3, 0xA7, 0x8D, 0x9C, 0xBA, 0xC2, 0x89, 0xD3, 0xC3, 0xAC, 0x98, 0x96, 0xA4, 0xE0, 0xC0, 0x81, 0x83, 0x86, 0x8C, 0x98, 0xB0, 0xE0, 0xCC, 0x89, 0x93, 0xC6, 0xCC, 0x9A, 0xE4, 0xC8, 0x99, 0xE3, 0x82, 0xEE, 0xD8, 0x97, 0xED, 0xC2, 0xCD, 0x9B, 0xD7, 0xCC, 0x99, 0xB3, 0xE5, 0xC6, 0xD1, 0xEB, 0xB2, 0xA6, 0x8B, 0xB8, 0xE3, 0xD8, 0xC4, 0xA1, 0x83, 0xC6, 0x8C, 0x9C, 0xB6, 0xF0, 0xD0, 0xC1, 0x93, 0x87, 0xCB, 0xB2, 0xEE, 0x88, 0x95, 0xD2, 0x80, 0x80 }; + string skeys = ""; + foreach (byte b in skey) + skeys += (char)b; + + PssConfig pssConfig = new PssConfig() + { + mAddress = "playersyncservices.ea.com", + mInitialReportTypes = PssReportTypes.None, + mNpCommSignature = null, + mOfferIds = null, + mPort = 443, + mProjectId = "303107", + mTitleId = 0, + }; + + GetTelemetryServerResponse getTelemetryServerResponse = new GetTelemetryServerResponse() + { + mAddress = "telemetry.ea.com", //"159.153.235.32", + mDisable = "AD,AF,AG,AI,AL,AM,AN,AO,AQ,AR,AS,AW,AX,AZ,BA,BB,BD,BF,BH,BI,BJ,BM,BN,BO,BR,BS,BT,BV,BW,BY,BZ,CC,CD,CF,CG,CI,CK,CL,CM,CN,CO,CR,CU,CV,CX,DJ,DM,DO,DZ,EC,EG,EH,ER,ET,FJ,FK,FM,FO,GA,GD,GE,GF,GG,GH,GI,GL,GM,GN,GP,GQ,GS,GT,GU,GW,GY,HM,HN,HT,ID,IL,IM,IN,IO,IQ,IR,IS,JE,JM,JO,KE,KG,KH,KI,KM,KN,KP,KR,KW,KY,KZ,LA,LB,LC,LI,LK,LR,LS,LY,MA,MC,MD,ME,MG,MH,ML,MM,MN,MO,MP,MQ,MR,MS,MU,MV,MW,MY,MZ,NA,NC,NE,NF,NG,NI,NP,NR,NU,OM,PA,PE,PF,PG,PH,PK,PM,PN,PS,PW,PY,QA,RE,RS,RW,SA,SB,SC,SD,SG,SH,SJ,SL,SM,SN,SO,SR,ST,SV,SY,SZ,TC,TD,TF,TG,TH,TJ,TK,TL,TM,TN,TO,TT,TV,TZ,UA,UG,UM,UY,UZ,VA,VC,VE,VG,VN,VU,WF,WS,YE,YT,ZM,ZW,ZZ", + mFilter = "-UION/****", + mIsAnonymous = true, + mKey = skeys, + mLocale = 1701725253, + mNoToggleOk = "US,CA,MX", + mPort = 9988, + mSendDelay = 15000, + mSendPercentage = 75, + mSessionID = "JMhnT9dXSED", + mUseServerTime = "", + }; + + GetTickerServerResponse getTickerServerResponse = new GetTickerServerResponse() + { + mAddress = "ticker.ea.com", + mKey = "823287263,10.23.15.2:8999,masseffect-3-ps3,10,50,50,50,50,0,12", + mPort = 8999 + }; + + UserOptions userOptions = new UserOptions() + { + mTelemetryOpt = TelemetryOpt.TELEMETRY_OPT_IN, + mUserId = 1 + }; + + PostAuthResponse postAuthResponse = new PostAuthResponse() + { + mPssConfig = pssConfig, + mTelemetryServer = getTelemetryServerResponse, + mTickerServer = getTickerServerResponse, + mUserOptions = userOptions, + + }; + + //return the response + return Task.FromResult(postAuthResponse); + } + + /// + /// You only need to override the base method to handle new requests. + /// If the request type or/and response type is NullStruct, you can change the request/response types in the Component Base. + /// + public override Task FetchClientConfigAsync(FetchClientConfigRequest request, BlazeRpcContext context) + { + //if needded access underlying connection which issued the request and other stuff + ProtoFireConnection connection = context.Connection; + + //manually displaying some data + LoggerAccessor.LogInfo($"[Blaze] - Util: Connection Id : {connection.ID}"); + LoggerAccessor.LogInfo($"[Blaze] - Util: mConfigSection : {request.mConfigSection}"); + + string ME3ClientConfig = Directory.GetCurrentDirectory() + "/static/EA/ME3_CONFIG/"; + Directory.CreateDirectory(ME3ClientConfig); + string filePathFull = ME3ClientConfig + request.mConfigSection + ".txt"; + + var fileClientConfigDictionary = new SortedDictionary(); + + + switch(request.mConfigSection) + { + case "ME3_DATA": + if (File.Exists(filePathFull)) + { + string[] fileConfig = File.ReadAllLines(filePathFull); + + for (int i = 0; i < fileConfig.Length; i++) + { + string[] parts = fileConfig[i].Split(';'); + + fileClientConfigDictionary.Add(parts[0].Trim(), parts[1].Trim()); + } + } + else + { + LoggerAccessor.LogWarn($"File not found! Path expected: {filePathFull}"); + } + + break; + case "ME3_MSG": + if (File.Exists(filePathFull)) + { + string[] fileConfig = File.ReadAllLines(filePathFull); + + for (int i = 0; i < fileConfig.Length; i++) + { + string[] parts = fileConfig[i].Split(';'); + + fileClientConfigDictionary.Add(parts[0].Trim(), parts[1].Trim()); + } + } + else + { + LoggerAccessor.LogWarn($"File not found! Path expected: {filePathFull}"); + } + + break; + case "ME3_ENT": + if (File.Exists(filePathFull)) + { + string[] fileConfig = File.ReadAllLines(filePathFull); + + for (int i = 0; i < fileConfig.Length; i++) + { + string[] parts; + if (!fileConfig[i].Trim().StartsWith("ENT_ENC")) + parts = fileConfig[i].Split(';'); + else + parts = fileConfig[i].Split(':'); + + fileClientConfigDictionary.Add(parts[0].Trim(), parts[1].Trim()); + } + } + else + { + LoggerAccessor.LogWarn($"File not found! Path expected: {filePathFull}"); + } + + break; + case "ME3_DIME": + if (File.Exists(filePathFull)) + { + string fileConfig = File.ReadAllText(filePathFull); + + + fileClientConfigDictionary.Add("Config", fileConfig); + } + else + { + LoggerAccessor.LogWarn($"File not found! Path expected: {filePathFull}"); + } + + break; + } + + + + FetchConfigResponse responseData = new FetchConfigResponse() + { + mConfig = fileClientConfigDictionary + }; + + + //return the response + return Task.FromResult(responseData); + } + + /// + /// You only need to override the base method to handle new requests. + /// If the request type or/and response type is NullStruct, you can change the request/response types in the Component Base. + /// + public override Task PingAsync(NullStruct request, BlazeRpcContext context) + { + //if needded access underlying connection which issued the request and other stuff + ProtoFireConnection connection = context.Connection; + + //manually displaying some data + LoggerAccessor.LogInfo($"[Blaze] - Util: Ping Connection Id : {connection.ID}"); + + DateTime dateTime = DateTime.Now; + + + PingResponse pingResponse = new() + { + mServerTime = uint.Parse(dateTime.ToString("yyyyMMdd")) + }; + + //return the response + return Task.FromResult(pingResponse); + } + } +} diff --git a/SpecializedServers/MultiSocks/Blaze/Redirector/RedirectorComponent.cs b/SpecializedServers/MultiSocks/Blaze/Redirector/RedirectorComponent.cs index c61f86135..e344074f7 100644 --- a/SpecializedServers/MultiSocks/Blaze/Redirector/RedirectorComponent.cs +++ b/SpecializedServers/MultiSocks/Blaze/Redirector/RedirectorComponent.cs @@ -4,6 +4,7 @@ using BlazeCommon; using CustomLogger; using MultiSocks.Utils; +using System.Net; namespace MultiSocks.Blaze.Redirector { @@ -37,7 +38,7 @@ public override Task GetServerInstanceAsync(ServerInstanceRe //Connection details bool secure = false; //insecure - string ip = "127.0.0.1"; + string ip = MultiSocksServerConfiguration.UsePublicIPAddress ? NetworkLibrary.TCP_IP.IPUtils.GetPublicIPAddress() : NetworkLibrary.TCP_IP.IPUtils.GetLocalIPAddress().ToString(); ushort port = 33152; ServerInstanceInfo responseData = new() diff --git a/SpecializedServers/MultiSocks/ProtoSSL/VulnerableCertificateGenerator.cs b/SpecializedServers/MultiSocks/ProtoSSL/VulnerableCertificateGenerator.cs index af8d68a83..5f0a216f7 100644 --- a/SpecializedServers/MultiSocks/ProtoSSL/VulnerableCertificateGenerator.cs +++ b/SpecializedServers/MultiSocks/ProtoSSL/VulnerableCertificateGenerator.cs @@ -56,9 +56,9 @@ public class VulnerableCertificateGenerator return creds; } - public (AsymmetricKeyParameter, Certificate, X509Certificate2) GetVulnerableCustomEaCert(string CN, string email) + public (AsymmetricKeyParameter, Certificate, X509Certificate2) GetVulnerableCustomEaCert(string CN, string email, string OU = "Online Technology Group") { - string SubjectDN = $"C=US, ST=California, O=\"Electronic Arts, Inc.\", OU=Online Technology Group, CN={CN}, emailAddress={email}"; + string SubjectDN = $"C=US, ST=California, O=\"Electronic Arts, Inc.\", OU={OU}, CN={CN}, emailAddress={email}"; if (_certCache.TryGetValue(CN, out (AsymmetricKeyParameter, Certificate, X509Certificate2) cacheHit)) // !TODO: New connections will break after running 10 years without a restart diff --git a/SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/ME3DATA - Copy.txt b/SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/ME3DATA - Copy.txt new file mode 100644 index 000000000..609c2944d --- /dev/null +++ b/SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/ME3DATA - Copy.txt @@ -0,0 +1,16 @@ +GAW_SERVER_BASE_URL ; http://waleu2.tools.gos.ea.com/wal/masseffect-gaw-pc +IMG_MNGR_BASE_URL ; http://me3.goscontent.ea.com/editorial/MassEffect/3/ +IMG_MNGR_MAX_BYTES ; 1048576 +IMG_MNGR_MAX_IMAGES ; 5 +JOB_THROTTLE_0 ; 10000 +JOB_THROTTLE_1 ; 5000 +JOB_THROTTLE_2 ; 1000 +MATCH_MAKING_RULES_VERSION ; 5 +MULTIPLAYER_PROTOCOL_VERSION ; 3 +TEL_DISABLE ; AD,AF,AG,AI,AL,AM,AN,AO,AQ,AR,AS,AW,AX,AZ,BA,BB,BD,BF,BH,BI,BJ,BM,BN,BO,BR,BS,BT,BV,BW,BY,BZ,CC,CD,CF,CG,CI,CK,CL,CM,CN,CO,CR,CU,CV,CX,DJ,DM,DO,DZ,EC,EG,EH,ER,ET,FJ,FK,FM,FO,GA,GD,GE,GF,GG,GH,GI,GL,GM,GN,GP,GQ,GS,GT,GU,GW,GY,HM,HN,HT,ID,IL,IM,IN,IO,IQ,IR,IS,JE,JM,JO,KE,KG,KH,KI,KM,KN,KP,KR,KW,KY,KZ,LA,LB,LC,LI,LK,LR,LS,LY,MA,MC,MD,ME,MG,MH,ML,MM,MN,MO,MP,MQ,MR,MS,MU,MV,MW,MY,MZ,NA,NC,NE,NF,NG,NI,NP,NR,NU,OM,PA,PE,PF,PG,PH,PK,PM,PN,PS,PW,PY,QA,RE,RS,RW,SA,SB,SC,SD,SG,SH,SJ,SL,SM,SN,SO,SR,ST,SV,SY,SZ,TC,TD,TF,TG,TH,TJ,TK,TL,TM,TN,TO,TT,TV,TZ,UA,UG,UM,UY,UZ,VA,VC,VE,VG,VN,VU,WF,WS,YE,YT,ZM,ZW,ZZ +TEL_DOMAIN ; pc/masseffect-3-pc-anon +TEL_FILTER ; -UION/**** +TEL_PORT ; 9988 +TEL_SEND_DELAY ; 15000 +TEL_SEND_PCT ; 75 +TEL_SERVER ; 159.153.235.32 \ No newline at end of file diff --git a/SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/ME3_DATA.txt b/SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/ME3_DATA.txt new file mode 100644 index 000000000..075c0bf78 --- /dev/null +++ b/SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/ME3_DATA.txt @@ -0,0 +1,16 @@ +GAW_SERVER_BASE_URL ; http://waleu2.tools.gos.ea.com/wal/masseffect-gaw-ps3 +IMG_MNGR_BASE_URL ; http://me3.goscontent.ea.com/editorial/MassEffect/3/ +IMG_MNGR_MAX_BYTES ; 1048576 +IMG_MNGR_MAX_IMAGES ; 5 +JOB_THROTTLE_0 ; 10000 +JOB_THROTTLE_1 ; 5000 +JOB_THROTTLE_2 ; 1000 +MATCH_MAKING_RULES_VERSION ; 5 +MULTIPLAYER_PROTOCOL_VERSION ; 3 +TEL_DISABLE ; AD,AF,AG,AI,AL,AM,AN,AO,AQ,AR,AS,AW,AX,AZ,BA,BB,BD,BF,BH,BI,BJ,BM,BN,BO,BR,BS,BT,BV,BW,BY,BZ,CC,CD,CF,CG,CI,CK,CL,CM,CN,CO,CR,CU,CV,CX,DJ,DM,DO,DZ,EC,EG,EH,ER,ET,FJ,FK,FM,FO,GA,GD,GE,GF,GG,GH,GI,GL,GM,GN,GP,GQ,GS,GT,GU,GW,GY,HM,HN,HT,ID,IL,IM,IN,IO,IQ,IR,IS,JE,JM,JO,KE,KG,KH,KI,KM,KN,KP,KR,KW,KY,KZ,LA,LB,LC,LI,LK,LR,LS,LY,MA,MC,MD,ME,MG,MH,ML,MM,MN,MO,MP,MQ,MR,MS,MU,MV,MW,MY,MZ,NA,NC,NE,NF,NG,NI,NP,NR,NU,OM,PA,PE,PF,PG,PH,PK,PM,PN,PS,PW,PY,QA,RE,RS,RW,SA,SB,SC,SD,SG,SH,SJ,SL,SM,SN,SO,SR,ST,SV,SY,SZ,TC,TD,TF,TG,TH,TJ,TK,TL,TM,TN,TO,TT,TV,TZ,UA,UG,UM,UY,UZ,VA,VC,VE,VG,VN,VU,WF,WS,YE,YT,ZM,ZW,ZZ +TEL_DOMAIN ; ps3/masseffect-3-ps3-anon +TEL_FILTER ; -UION/**** +TEL_PORT ; 9988 +TEL_SEND_DELAY ; 15000 +TEL_SEND_PCT ; 75 +TEL_SERVER ; 159.153.235.32 \ No newline at end of file diff --git a/SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/ME3_DIME.txt b/SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/ME3_DIME.txt new file mode 100644 index 000000000..dc92ec920 --- /dev/null +++ b/SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/ME3_DIME.txt @@ -0,0 +1,46 @@ + + + 1 + 1 + + + 0 + Mass Effect 3 + + 10285 + 10398 + 10397 + 13339 + ME3PCContent + https://origin.checkout.ea.com/lockbox-ui/checkout + http://bioware.com + http://bioware.com + _BW + + + 0 + + + +0x30D40ME3 RePack Silver0OFB-MASS:46192truetrueOFB-MASS:46192ME3_REPACK_SILVER_PACKtrue00 +0x3D090ME3 RePack Silver Premium0OFB-MASS:48173truetrueOFB-MASS:48173ME3_REPACK_SILVER_PREMIUM_PACKtrue00 +0x493E0ME3 RePack Gold0OFB-MASS:46193truetrueOFB-MASS:46193ME3_REPACK_GOLD_PACKtrue00 +0x55730ME3 RePack Gold Premium0OFB-MASS:48177truetrueOFB-MASS:48177ME3_REPACK_GOLD_PREMIUM_PACKtrue00 +0x495D4ME3 RePack Gold Jumbo0OFB-MASS:48189truetrueOFB-MASS:48189ME3_REPACK_GOLD_JUMBO_PACKtrue00 +0x61A80ME3 RePack Platinum0OFB-MASS:46194truetrueOFB-MASS:46194ME3_REPACK_PLATINUM_PACKtrue00 +0x61A82ME3 RePack Platinum Deal 20OFB-MASS:48194truetrueOFB-MASS:48194ME3_REPACK_PLATINUM_PACKtrue00 +0x7A120ME3 RePack Supplies0OFB-MASS:48196truetrueOFB-MASS:48196ME3_REPACK_SUPPLIES_PACKtrue00 +0x7A314ME3 RePack Supplies Jumbo0OFB-MASS:48199truetrueOFB-MASS:48199ME3_REPACK_SUPPLIES_JUMBO_PACKtrue00 +0x7A508ME3 RePack Mystery Character0OFB-MASS:48201truetrueOFB-MASS:48201ME3_REPACK_MYSTERY_CHARACTERtrue00 +0x7A8F0ME3 RePack Mystery Weapon0OFB-MASS:48202truetrueOFB-MASS:48202ME3_REPACK_MYSTERY_WEAPONtrue00 +0x7ACD8ME3 RePack Mystery Mod0OFB-MASS:48203truetrueOFB-MASS:48203ME3_REPACK_MYSTERY_MODtrue00 +0x9EB12ME3 RePack Resurgence Deal 20OFB-MASS:48326truetrueOFB-MASS:48326ME3_REPACK_RESURGENCE_01true00 +0x9EB13ME3 RePack Rebellion0OFB-MASS:49749truetrueOFB-MASS:49749ME3_REPACK_REBELLIONtrue00 +0x9EB14ME3 RePack Rebellion Deal 10OFB-MASS:49750truetrueOFB-MASS:49750ME3_REPACK_REBELLIONtrue00 +0x9EB15ME3 RePack Rebellion Deal 20OFB-MASS:49751truetrueOFB-MASS:49751ME3_REPACK_REBELLIONtrue00 +0x9EB74N7 Equipment Pack0OFB-MASS:50162truetrueOFB-MASS:50162ME3_REPACK_N7_EQUIPMENTtrue00 +0x9EBD8Arsenal Pack0OFB-MASS:50165truetrueOFB-MASS:50165ME3_REPACK_ARSENALtrue00 +0x9EC3CReserves Pack0OFB-MASS:50166truetrueOFB-MASS:50166ME3_REPACK_RESERVEStrue00 + + + \ No newline at end of file diff --git a/SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/ME3_ENT.txt b/SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/ME3_ENT.txt new file mode 100644 index 000000000..a9cbe2ffe --- /dev/null +++ b/SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/ME3_ENT.txt @@ -0,0 +1,343 @@ +CERBERUS_OFFER_ID ; 101 +ENT_100_entitlement ; ME3_PRC_MP5 +ENT_100_group ; ME3PCContent +ENT_100_ID ; 3225 +ENT_100_param ; MP_DLC=TRUE&stringref=782577 +ENT_101_entitlement ; BWE_ANCILLARY_DH_SX3_FIGHTER +ENT_101_group ; ME3GenAncillary +ENT_101_ID ; 1250033 +ENT_102_entitlement ; BWE_ANCILLARY_TALI_BISHOUJO +ENT_102_group ; ME3GenAncillary +ENT_102_ID ; 1250034 +ENT_103_entitlement ; BWE_ANCILLARY_N7_WATCH +ENT_103_group ; ME3GenAncillary +ENT_103_ID ; 1250035 +ENT_104_entitlement ; BWE_ANCILLARY_N7_SNEAKER +ENT_104_group ; ME3GenAncillary +ENT_104_ID ; 1250036 +ENT_105_entitlement ; BWE_ANCILLARY_NORMANDY_SNOWBOARD +ENT_105_group ; ME3GenAncillary +ENT_105_ID ; 1250037 +ENT_106_entitlement ; BWE_ANCILLARY_GARRUS_BUST +ENT_106_group ; ME3GenAncillary +ENT_106_ID ; 1250038 +ENT_107_entitlement ; BWE_ANCILLARY_MORDIN_BUST +ENT_107_group ; ME3GenAncillary +ENT_107_ID ; 1250039 +ENT_108_entitlement ; ME3_PRO_COMMEND_21 +ENT_108_group ; ME3GenContent +ENT_108_ID ; 1500021 +ENT_109_entitlement ; ME3_PRO_CHALLENGE_21 +ENT_109_group ; ME3PCOffers +ENT_109_ID ; 1500121 +ENT_10_entitlement ; ME3_PRO_MAGICAL_01 +ENT_10_group ; ME3GenOffers +ENT_10_ID ; 2000000 +ENT_110_entitlement ; ME3_PRO_COMMEND_22 +ENT_110_group ; ME3GenContent +ENT_110_ID ; 1500022 +ENT_111_entitlement ; ME3_PRO_CHALLENGE_22 +ENT_111_group ; ME3PCOffers +ENT_111_ID ; 1500122 +ENT_112_entitlement ; ME3_PRO_COMMEND_23 +ENT_112_group ; ME3GenContent +ENT_112_ID ; 1500023 +ENT_113_entitlement ; ME3_PRO_CHALLENGE_23 +ENT_113_group ; ME3PCOffers +ENT_113_ID ; 1500123 +ENT_114_entitlement ; BWE_ANCILLARY_ME3_FEMSHEP_BISHOUJO +ENT_114_group ; ME3GenAncillary +ENT_114_ID ; 1250040 +ENT_11_entitlement ; ME3_PRO_COMMEND_09 +ENT_11_group ; ME3GenContent +ENT_11_ID ; 1500008 +ENT_12_entitlement ; ME3_PRO_COMMEND_10 +ENT_12_group ; ME3GenContent +ENT_12_ID ; 1500009 +ENT_13_entitlement ; ME3_CS_CREDITS_01 +ENT_13_group ; ME3GenContent +ENT_13_ID ; 1300000 +ENT_14_entitlement ; ME3_PRC_REBELLION +ENT_14_group ; ME3PCContent +ENT_14_ID ; 2500 +ENT_14_param ; MP_DLC=TRUE&stringref=735694&MP_Maps=BioP_MPJngl&MP_Maps=BioP_MPThes +ENT_15_entitlement ; ME3_REINF_PACK_PURCHASED +ENT_15_group ; ME3PCOffers +ENT_15_ID ; 4000112 +ENT_15_param ; Grant:Group=ME3PCOffers&Grant:Tag=ME3_REINF_PACK_PURCHASED +ENT_16_entitlement ; ME3_PRO_RECRU_REPACK_LOYALTYPACK_01 +ENT_16_group ; ME3GenContent +ENT_16_ID ; 1100001 +ENT_17_entitlement ; ME3_PRO_RECRU_REPACK_LOYALTYPACK_02 +ENT_17_group ; ME3GenContent +ENT_17_ID ; 1100002 +ENT_18_entitlement ; ME3_PRO_RECRU_REPACK_LOYALTYPACK_03 +ENT_18_group ; ME3GenContent +ENT_18_ID ; 1100003 +ENT_19_entitlement ; ME3_PRO_RECRU_REPACK_LOYALTYPACK_04 +ENT_19_group ; ME3GenContent +ENT_19_ID ; 1100004 +ENT_1_group ; ME3PCOffers +ENT_20_entitlement ; ME3_PRO_RECRU_REPACK_LOYALTYPACK_05 +ENT_20_group ; ME3GenContent +ENT_20_ID ; 1100005 +ENT_21_entitlement ; BWE_ANCILLARY_LIARA_STATUE +ENT_21_group ; ME3GenAncillary +ENT_21_ID ; 1250001 +ENT_22_entitlement ; BWE_ANCILLARY_N7_MOUSE +ENT_22_group ; ME3GenAncillary +ENT_22_ID ; 1250002 +ENT_23_entitlement ; BWE_ANCILLARY_N7_KEYBOARD +ENT_23_group ; ME3GenAncillary +ENT_23_ID ; 1250003 +ENT_24_entitlement ; BWE_ANCILLARY_N7_MOUSEPAD +ENT_24_group ; ME3GenAncillary +ENT_24_ID ; 1250004 +ENT_25_entitlement ; BWE_ANCILLARY_N7_XBOX_CONTROLLER +ENT_25_group ; ME3GenAncillary +ENT_25_ID ; 1250005 +ENT_26_entitlement ; BWE_ANCILLARY_N7_XBOX_HEADSET +ENT_26_group ; ME3GenAncillary +ENT_26_ID ; 1250006 +ENT_27_entitlement ; BWE_ANCILLARY_N7_LAPTOP_BAG +ENT_27_group ; ME3GenAncillary +ENT_27_ID ; 1250007 +ENT_28_entitlement ; BWE_ANCILLARY_N7_IPHONE_CASE +ENT_28_group ; ME3GenAncillary +ENT_28_ID ; 1250008 +ENT_29_entitlement ; BWE_ANCILLARY_N7_IPAD_CASE +ENT_29_group ; ME3GenAncillary +ENT_29_ID ; 1250009 +ENT_2_group ; ME3PCContent +ENT_30_entitlement ; BWE_ANCILLARY_MIRANDA_FIGURE +ENT_30_group ; ME3GenAncillary +ENT_30_ID ; 1250010 +ENT_31_entitlement ; BWE_ANCILLARY_MORDIN_FIGURE +ENT_31_group ; ME3GenAncillary +ENT_31_ID ; 1250011 +ENT_32_entitlement ; BWE_ANCILLARY_LEGION_FIGURE +ENT_32_group ; ME3GenAncillary +ENT_32_ID ; 1250012 +ENT_33_entitlement ; BWE_ANCILLARY_GARRUS_FIGURE +ENT_33_group ; ME3GenAncillary +ENT_33_ID ; 1250013 +ENT_34_entitlement ; BWE_ANCILLARY_TALI_FIGURE +ENT_34_group ; ME3GenAncillary +ENT_34_ID ; 1250014 +ENT_35_entitlement ; BWE_ANCILLARY_GRUNT_FIGURE +ENT_35_group ; ME3GenAncillary +ENT_35_ID ; 1250015 +ENT_36_entitlement ; BWE_ANCILLARY_THANE_FIGURE +ENT_36_group ; ME3GenAncillary +ENT_36_ID ; 1250016 +ENT_37_entitlement ; BWE_ANCILLARY_SHEPARD_FIGURE +ENT_37_group ; ME3GenAncillary +ENT_37_ID ; 1250017 +ENT_38_entitlement ; BWE_ANCILLARY_APPAREL +ENT_38_group ; ME3GenAncillary +ENT_38_ID ; 1250018 +ENT_39_entitlement ; BWE_ANCILLARY_DH_ARTBOOK +ENT_39_group ; ME3GenAncillary +ENT_39_ID ; 1250019 +ENT_3_group ; ME3GenOffers +ENT_40_entitlement ; ME3_PRC_RESURGENCE +ENT_40_group ; ME3PCContent +ENT_40_ID ; 2300 +ENT_40_param ; MP_DLC=TRUE&stringref=728589&MP_Maps=BioP_MPGeth&MP_Maps=BioP_MPMoon +ENT_41_entitlement ; ME3_PRO_MAGICAL_02 +ENT_41_group ; ME3GenOffers +ENT_41_ID ; 2000001 +ENT_42_entitlement ; BW_ANCILLARY_ALLIANCE_NORMANDY +ENT_42_group ; ME3GenAncillary +ENT_42_ID ; 1250020 +ENT_43_entitlement ; BW_ANCILLARY_CERBERUS_NORMANDY +ENT_43_group ; ME3GenAncillary +ENT_43_ID ; 1250021 +ENT_44_entitlement ; BWE_ANCILLARY_TRIFORCE_M8 +ENT_44_group ; ME3GenAncillary +ENT_44_ID ; 1250022 +ENT_45_entitlement ; BWE_ANCILLARY_CALIBUR11_CONSOLE +ENT_45_group ; ME3GenAncillary +ENT_45_ID ; 1250023 +ENT_46_entitlement ; BWE_ANCILLARY_SILVER_NORMANDY +ENT_46_group ; ME3GenAncillary +ENT_46_ID ; 1250024 +ENT_47_entitlement ; BWE_ANCILLARY_DH_DIGARTBOOK +ENT_47_group ; ME3GenAncillary +ENT_47_ID ; 1250025 +ENT_48_entitlement ; BWE_ANCILLARY_DH_DIGINVASION +ENT_48_group ; ME3GenAncillary +ENT_48_ID ; 1250026 +ENT_49_entitlement ; ME3_PRO_COMMEND_01 +ENT_49_group ; ME3GenContent +ENT_49_ID ; 1500000 +ENT_4_group ; ME3GenContent +ENT_50_entitlement ; ME3_PRO_COMMEND_O2 +ENT_50_group ; ME3GenContent +ENT_50_ID ; 1500001 +ENT_51_entitlement ; ME3_PRO_COMMEND_03 +ENT_51_group ; ME3GenContent +ENT_51_ID ; 1500002 +ENT_52_entitlement ; ME3_PRO_COMMEND_04 +ENT_52_group ; ME3GenContent +ENT_52_ID ; 1500003 +ENT_53_entitlement ; ME3_PRO_COMMEND_05 +ENT_53_group ; ME3GenContent +ENT_53_ID ; 1500004 +ENT_54_entitlement ; ME3_PRO_COMMEND_06 +ENT_54_group ; ME3GenContent +ENT_54_ID ; 1500005 +ENT_55_entitlement ; ME3_PRO_COMMEND_07 +ENT_55_group ; ME3GenContent +ENT_55_ID ; 1500006 +ENT_56_entitlement ; ME3_PRO_COMMEND_08 +ENT_56_group ; ME3GenContent +ENT_56_ID ; 1500007 +ENT_57_entitlement ; ME3_PRC_EARTH +ENT_57_group ; ME3PCContent +ENT_57_ID ; 2700 +ENT_57_param ; MP_DLC=TRUE&stringref=747202&MP_Maps=BioP_MPHosp&MP_Maps=BioP_MPOcean&MP_Maps=BioP_MPRoad +ENT_58_entitlement ; ME3_MP2_PRESSUNLOCK +ENT_58_group ; ME3GenContent +ENT_58_ID ; 1300001 +ENT_59_entitlement ; BWE_ANCILLARY_FEMSHEP_STATUE +ENT_59_group ; ME3GenAncillary +ENT_59_ID ; 1250028 +ENT_5_group ; ME3GenAncillary +ENT_60_entitlement ; BWE_ANCILLARY_SHEPARD_STATUE +ENT_60_group ; ME3GenAncillary +ENT_60_ID ; 1250029 +ENT_61_entitlement ; BWE_ANCILLARY_TRIFORCE_M3 +ENT_61_group ; ME3GenAncillary +ENT_61_ID ; 1250030 +ENT_62_entitlement ; ME3_PRC_GOBIG +ENT_62_group ; ME3PCContent +ENT_62_ID ; 3050 +ENT_62_param ; MP_DLC=TRUE&stringref=768382&MP_Maps=BioP_MPNov2&MP_Maps=BioP_MPCer2&MP_Maps=BioP_MPDish2&MP_Maps=BioP_MPRctr2&MP_Maps=BioP_MPSlum2&MP_Maps=BioP_MPTowr2&MP_Maps=BioP_MPTowr3&MP_Maps=BioP_MPNov3&MP_Maps=BioP_MPCer3 +ENT_63_entitlement ; BWE_ANCILLARY_ASHLEY_STATUE +ENT_63_group ; ME3GenAncillary +ENT_63_ID ; 1250031 +ENT_64_entitlement ; ME3_CS_CREDITS_02 +ENT_64_group ; ME3GenContent +ENT_64_ID ; 1300005 +ENT_65_entitlement ; ME3_CS_CREDITS_03 +ENT_65_group ; ME3GenContent +ENT_65_ID ; 1300006 +ENT_66_entitlement ; ME3_PRO_COMMEND_11 +ENT_66_group ; ME3GenContent +ENT_66_ID ; 1500010 +ENT_67_entitlement ; ME3_PRO_COMMEND_12 +ENT_67_group ; ME3GenContent +ENT_67_ID ; 1500011 +ENT_68_entitlement ; ME3_PRO_COMMEND_13 +ENT_68_group ; ME3GenContent +ENT_68_ID ; 1500012 +ENT_69_entitlement ; ME3_PRO_COMMEND_14 +ENT_69_group ; ME3GenContent +ENT_69_ID ; 1500013 +ENT_6_entitlement ; BF3:PC:ADDSVETRANK +ENT_6_group ; AddsVetRank +ENT_6_ID ; 1150000 +ENT_70_entitlement ; ME3_PRO_COMMEND_15 +ENT_70_group ; ME3GenContent +ENT_70_ID ; 1500014 +ENT_71_entitlement ; ME3_PRO_COMMEND_16 +ENT_71_group ; ME3GenContent +ENT_71_ID ; 1500015 +ENT_72_entitlement ; ME3_PRO_COMMEND_17 +ENT_72_group ; ME3GenContent +ENT_72_ID ; 1500016 +ENT_73_entitlement ; ME3_PRO_COMMEND_18 +ENT_73_group ; ME3GenContent +ENT_73_ID ; 1500017 +ENT_74_entitlement ; ME3_PRO_COMMEND_19 +ENT_74_group ; ME3GenContent +ENT_74_ID ; 1500018 +ENT_75_entitlement ; ME3_PRO_COMMEND_20 +ENT_75_group ; ME3GenContent +ENT_75_ID ; 1500019 +ENT_76_entitlement ; ME3_PRO_CHALLENGE_01 +ENT_76_group ; ME3PCOffers +ENT_76_ID ; 1500101 +ENT_77_entitlement ; ME3_PRO_CHALLENGE_02 +ENT_77_group ; ME3PCOffers +ENT_77_ID ; 1500102 +ENT_78_entitlement ; ME3_PRO_CHALLENGE_03 +ENT_78_group ; ME3PCOffers +ENT_78_ID ; 1500103 +ENT_79_entitlement ; ME3_PRO_CHALLENGE_04 +ENT_79_group ; ME3PCOffers +ENT_79_ID ; 1500104 +ENT_7_entitlement ; PROJECT10_CODE_CONSUMED +ENT_7_group ; ME3PCOffers +ENT_7_ID ; 101 +ENT_80_entitlement ; ME3_PRO_CHALLENGE_05 +ENT_80_group ; ME3PCOffers +ENT_80_ID ; 1500105 +ENT_81_entitlement ; ME3_PRO_CHALLENGE_06 +ENT_81_group ; ME3PCOffers +ENT_81_ID ; 1500106 +ENT_82_entitlement ; ME3_PRO_CHALLENGE_07 +ENT_82_group ; ME3PCOffers +ENT_82_ID ; 1500107 +ENT_83_entitlement ; ME3_PRO_CHALLENGE_08 +ENT_83_group ; ME3PCOffers +ENT_83_ID ; 1500108 +ENT_84_entitlement ; ME3_PRO_CHALLENGE_09 +ENT_84_group ; ME3PCOffers +ENT_84_ID ; 1500109 +ENT_85_entitlement ; ME3_PRO_CHALLENGE_10 +ENT_85_group ; ME3PCOffers +ENT_85_ID ; 1500110 +ENT_86_entitlement ; ME3_PRO_CHALLENGE_11 +ENT_86_group ; ME3PCOffers +ENT_86_ID ; 1500111 +ENT_87_entitlement ; ME3_PRO_CHALLENGE_12 +ENT_87_group ; ME3PCOffers +ENT_87_ID ; 1500112 +ENT_88_entitlement ; ME3_PRO_CHALLENGE_13 +ENT_88_group ; ME3PCOffers +ENT_88_ID ; 1500113 +ENT_89_entitlement ; ME3_PRO_CHALLENGE_14 +ENT_89_group ; ME3PCOffers +ENT_89_ID ; 1500114 +ENT_8_entitlement ; PROJECT10_CODE_CONSUMED_LE1 +ENT_8_group ; ME3PCOffers +ENT_8_ID ; 102 +ENT_8_param ; BWID=101 +ENT_90_entitlement ; ME3_PRO_CHALLENGE_15 +ENT_90_group ; ME3PCOffers +ENT_90_ID ; 1500115 +ENT_91_entitlement ; ME3_PRO_CHALLENGE_16 +ENT_91_group ; ME3PCOffers +ENT_91_ID ; 1500116 +ENT_92_entitlement ; ME3_PRO_CHALLENGE_17 +ENT_92_group ; ME3PCOffers +ENT_92_ID ; 1500117 +ENT_93_entitlement ; ME3_PRO_CHALLENGE_18 +ENT_93_group ; ME3PCOffers +ENT_93_ID ; 1500118 +ENT_94_entitlement ; ME3_PRO_CHALLENGE_19 +ENT_94_group ; ME3PCOffers +ENT_94_ID ; 1500119 +ENT_95_entitlement ; ME3_PRO_CHALLENGE_20 +ENT_95_group ; ME3PCOffers +ENT_95_ID ; 1500120 +ENT_96_entitlement ; ME3_CS_SERVICE_01 +ENT_96_group ; ME3GenContent +ENT_96_ID ; 1400000 +ENT_97_entitlement ; ME3_CS_SERVICE_02 +ENT_97_group ; ME3GenContent +ENT_97_ID ; 1400001 +ENT_98_entitlement ; ME3_CS_SERVICE_03 +ENT_98_group ; ME3GenContent +ENT_98_ID ; 1400002 +ENT_99_entitlement ; BWE_ANCILLARY_ME_ANIME_MOVIE +ENT_99_group ; ME3GenAncillary +ENT_99_ID ; 1250032 +ENT_9_entitlement ; PROJECT10_CODE_CONSUMED_LE2 +ENT_9_group ; ME3PCOffers +ENT_9_ID ; 103 +ENT_9_param ; BWID=101 +ENT_ENC : 0051CCF2;00A35612;0163AA2E;01BCA74E;01D861E1;0237E3EE;02CE0DC0;0326FDCE;03C48303;04260DF1;04646BA5;04B2FED2;055C7130;05D148A4;0662323D;07035FB9;07A7AE9E;08229B6E;0889BCD8;092AEA54;0977008C;09D88B7A;0A2BB64D;0A2DA8F0;0A7ED87B;0B232351;0BC5F591;0C416811;0C9CAC4E;0D2F61F6;0D54EC69;0D6AB3C8;0D6E9BF3;0DDF15BB;0E73A766;0EE87EDA;0F9E1B18;0FB1A093;10214AD0;10CC021B;117D8A56;1198ADA6;11B02663;120F98D1;12CFBC47;12D38455;135C4DD3;13ABDEF7;1449DF3C;146157F9;146E963C;152176F4;15DF374C;16993403;16D72471;170A8EEF;1717CAB7;17B1CEC8;18231C67;18E3AABD;191525F6;198EE18D;1A061217;1A6DC5F8;1AF8925F;1B78A2C0;1BE4A383;1C46E07A;1CB7F53B;1D6DFD62;1DFB6F25;1E6BE8ED;1F2C55F1;1F368004;1F7A05F1;2035983D;20526BDF;20F8233E;2171DED5;21E90F5F;227367E9;22ECF94B;2308F10C;23115D87;235800A6;23E0CA24;24A2FDD0;24FFC609;25AC206A;266C43E0;2723BABE;2724F2C8;27949D05;28086089;285E36BF;28A39D8E;2906B6E2;29582956;299520D6;29AB3B75;29F96D75;2A28A0D2;2A5F9098;2A6CCEDB;2B25F583;2BBFD879;2C399410;2CB0C49A;2D18787B;2DA344E2;2E235543;2E8F5606;2EF192FD;2F62A7BE;2FE1485F;30088EA8;3074D615;30B3C215;310CBF35;31A08A94;31ABB3DB;3255B7D1;33162B72;332BA248;33D158DF;344B49F9;348584B1;348AF848;352BAAD2;3544BBB5;35BE18AC;363A6D46;36C0CF87;37622054;37C3AB42;383FFFDC;38E5B673;395FA78D;39853200;3A45A5A1;3A834631;3ABDCDD5;3ACB0C18;3B39D7DC;3B920685;3C09370F;3C938F99;3D0D20FB;3D2918BC;3D318537;3D782856;3E00F1D4;3EC32580;3F1FEDB9;3FCC481A;408C6B90;4143E26E;41451A78;41B4C4B5;42288839;427E5E6F;42C3C53E;4326DE92;43785106;43B54886;43CB6325;44199525;4448C882;447FB848;448CF68B;45461D33;45E00029;4659BBC0;46D0EC4A;4738A02B;47C36C92;48437CF3;48AF7DB6;4911BAAD;4982CF6E;4A01700F;4A28B658;4A94FDC5;4AD3E9C5;4B2CE6E5;4BC0B244;4C5485FD;4CFE89F3;4DBEFD94;4DD4746A;4E7A2B01;4EF41C1B;4F2E56D3;4F33CA6A;4FD47CF4;4FED8DD7;5066EACE;50E33F68;5169A1A9;520AF276;526C7D64;52E8D1FE;538E8895;540879AF;542E0422;54EE77C3;54FBB606;552E21A0;5546604F;55F3F579;56603CE6;570FC91C;5735538F;574B1AEE;574F0319;57BF7CE1;58540E8C;58C8E600;597E823E;599207B9;5A01B1F6;5AAC6941;5B5DF17C;5B7914CC;5B908D89;5BEFFFF7;5CB0236D;5CB3EB7B;5D3CB4F9;5D8C461D;5E2A4662;5E41BF1F;5E4EFD62;5F01DE1A;5FBF9E72;60799B29;60B78B97;60EAF615;60F831DD;60F974DF;61BBA89C;61EA4AC5;6277BC88;62E83650;63A8A354;63B2CD67;63F65354;64B1E5A0;64F402A8;652FBDA6;65A9793D;6620A9C7;66AB0251;672493B3;67408B74;6748F7EF;678F9B0E;6818648C;68DA9838;69376071;69E3BAD2;6AA3DE48;6B5B5526;6B5C8D30;6BCC376D;6C3FFAF1;6C95D127;6CDB37F6;6D3E514A;6DF05C34;6EB0C938;6F72FCF5;6FD61649;7071ADA3;70D9C83A;714E9FAE;71C85B45;723F8BCF;72A73FB0;73320C17;73B21C78;741E1D3B;74805A32;7498C9D7;74E65942;750D9F8B;7579E6F8;75B8D2F8;7611D018;76A59B77;76FE2104;77A824FA;7868989B;787E0F71;7923C608;799DB722;79D7F1DA;79DD6571;7A7E17FB;7A9728DE;7B1085D5;7B8CDA6F;7C133CB0;7CB48D7D;7D16186B;7D926D05;7E38239C;7EB214B6;7ED79F29;7F9812CA;7FD5B35A;7FFD9DA3;8028D283;802A728D;80D807B7;814F3841;81D990CB;8253222D;826F19EE;82778669;82BE2988;8346F306;840926B2;8465EEEB;8512494C;85D26CC2;8689E3A0;868B1BAA;86FAC5E7;876E896B;87C45FA1;8809C670;886CDFC4;89269055;89E3AAF8;8A58826C;8A9672DA;8AC9DD58;8AD71920;8AE44CA8;8B433902;8BC60AA0;8C537C63;8CC3F62B;8D84632F;8D8E8D42;8DD2132F;8E8DA57B;8ECFC283;8F8EFE50;9008B9E7;901C5C05;906DE525;912E3941;91873661;91A2F0F4;91BB7942;9251A314;92AA9322;93481857;93DACDFF;94337698;947EBF38;950F2197;951FDCC8;955F1FA3;960CB4CD;96890967;96EF8DFA;9790BB76;98350A5B;98AFF72B;99171895;99B84611;9A045C49;9A65E737;9AB9120A;9ABB04AD;9AFF0BB6;9B00AAD5;9B59536E;9BD4C5EE;9C4BF678;9CB3AA59;9D3E76C0;9DBE8721;9E2A87E4;9ECCB6A6;9F386BD2;9FB70C73;9FDE52BC;A04A9A29;A0898629;A0E28349;A1764EA8;A193224A;A23D2640;A2FD99E1;A31310B7;A334DC86;A33E56B1;A3B72CDA;A410DFB1;A4C0E63D;A4FB20F5;A5914AC7;A627993D;A6A0275E;A7198455;A795D8EF;A81C3B30;A8BD8BFD;A91F16EB;A99B6B85;AA41221C;AABB1336;AAE09DA9;AB1B3E37;AB6C6DC2;AC0A1123;AC6EB672;ACE66C23;AD56E5EB;ADEB7796;AE604F0A;AF15EB48;AF2970C3;AF991B00;B043D24B;B0F55A86;B1107DD6;B127F693;B1876901;B2478C77;B24B5485;B2D41E03;B323AF27;B3C1AF6C;B3D92829;B3E6666C;B4994724;B557077C;B6110433;B64EF4A1;B6825F1F;B68F9AE7;B6F8F289;B7AB911B;B7C309D8;B856C098;B8A17851;B92EEA14;B99F63DC;BA5FD0E0;BA69FAF3;BAAD80E0;BB69132C;BBAB3034;BBCDD1FE;BC478D95;BC5B2FB3;BCACB8D3;BD6D0CEF;BDC60A0F;BE4C0F9B;BE9A14D6;BF303EA8;BF892EB6;C026B3EB;C0883ED9;C0C69C8D;C1152FBA;C1BEA218;C233798C;C2C46325;C36590A1;C409DF86;C484CC56;C4EBEDC0;C58D1B3C;C5D93174;C5DB2417;C6537805;C65CF230;C68F5DCA;C6BBF9BE;C70A8CEB;C766EF03;C7B0232E;C7FB6BCE;C804B977;C8664465;C90D80FE;C9AED1CB;CA3C438E;CAACBD56;CB414F01;CBB62675;CC6BC2B3;CC7F482E;CCEEF26B;CD99A9B6;CE4B31F1;CE665541;CE7DCDFE;CEDD406C;CF9D63E2;CFA12BF0;D029F56E;D0798692;D11786D7;D12EFF94;D1B490B1;D214C6A2;D2D44A00;D38A9C39;D3B9CF96;D3F0BF5C;D4B22BC9;D4DC84B3;D4FFBA7F;D5BFDDF5;D639998C;D6B0CA16;D7187DF7;D7A34A5E;D8235ABF;D88F5B82;D8F19879;D90A081E;D9CC33C0;DA59A583;DACA1F4B;DB5EB0F6;DBD3886A;DC8924A8;DC9CAA23;DD0C5460;DDB70BAB;DE6893E6;DE83B736;DE9B2FF3;DEFAA261;DFBAC5D7;DFBE8DE5;E0475763;E096E887;E134E8CC;E14C6189;E1D1F2A6;E2314870;E2C882C1;E317880F;E360BC3A;E3D36CF2;E4106472;E4939586;E4D41C0C;E5618DCF;E5D20797;E692749B;E69C9EAE;E6E0249B;E79BB6E7;E7DDD3EF;E84B9FF7;E8C55B8E;E93C8C18;E9C6E4A2;EA407604;EA5C6DC5;EA64DA40;EAAB7D5F;EB3446DD;EBF67A89;EC5342C2;ECFF9D23;EDBFC099;EE773777;EE786F81;EEE819BE;EF5BDD42;EFB1B378;EFF71A47;F05A339B;F07AF187;F085FC0E;F0E25BAB;F15E37F5;F1DD7D0D;F1E829B2;F20A218E;F2979351;F3080D19;F3C87A1D;F3D2A430;F4162A1D;F4D1BC69;F513D971;F57967D0;F5F32367;F66A53F1;F6F4AC7B;F76E3DDD;F78A359E;F792A219;F7D94538;F8620EB6;F9244262;F9810A9B;FA2D64FC;FAED8872;FBA4FF50;FBA6375A;FC15E197;FC89A51B;FCDF7B51;FD24E220;FD87FB74;FE3F913B;FEC245C3;FF05CBB0;FF41B104;FF79FCE9;FFB0ECAF;0001002AA846;000100A1D8D0;000101098CB1;000101945918;000102146979;000102806A3C;000102E2A733;000102FB16D8;000103098FB8;00010397017B;000104077B43;000104C7E847;000104D2125A;000105159847;000105D12A93;00010657301F;000106AF9D92;000107295929;000107A089B3;000108083D94;0001089309FB;000109131A5C;0001097F1B1F;000109E15816;00010A0DE63D;00010A5B75A8;00010A82BBF1;00010AEF035E;00010B6DBE98;00010C243EB9;00010C7243F4;00010D086DC6;00010D615DD4;00010DFEE309;00010E606DF7;00010E9ECBAB;00010EED5ED8;00010F96D136;0001100BA8AA;0001109C9243;0001113DBFBF;000111E20EA4;0001125CFB74;000112C41CDE;000113654A5A;000113B16092;00011412EB80;000114661653;000115104F29;00011528F7CB;000115778AF8;0001159CF350;000115A66D7B;0001162F943F;0001169FBA5F;000116DB9FB3;0001171018F1;000117B467D6;000117FFB076;00011876E100;00011901398A;0001197ACAEC;00011996C2AD;0001199F2F28;000119E5D247;00011A6E9BC5;00011B30CF71;00011B8D97AA;00011C39F20B;00011CFA1581;00011DB18C5F;00011DB2C469;00011E226EA6;00011E96322A;00011EEC0860;00011F316F2F;00011F948883;0001204E3914;0001210B53B7;000121802B2B;000121BE1B99;000121F18617;000121FEC1DF;00012298C5F0;000122D85DC9;000122E30A6E;0001237614E7;0001240386AA;000124740072;000125346D76;0001253E9789;000125821D76;0001263DAFC2;0001267FCCCA;0001268AF173;00012704AD0A;0001277BDD94;00012806361E;0001287FC780;0001289BBF41;000128A42BBC;000128EACEDB;000129739859;00012A35CC05;00012A92943E;00012B3EEE9F;00012BFF1215;00012CB688F3;00012CB7C0FD;00012D276B3A;00012D9B2EBE;00012DF104F4;00012E366BC3;00012E998517;00012F4B9001;0001300BFD05;000130CE30C2;000131314A16;000131A7A548;00013241883E;000132E4C1DC;000133599950;000133D354E7;0001344A8571;000134B23952;0001353D05B9;000135BD161A;0001362916DD;0001368B53D4;000136A3C379;000136A56DD4;00013732DF97;000137A3595F;00013837EB0A;000138ACC27E;000139625EBC;00013975E437;000139E58E74;00013A9045BF;00013B41CDFA;00013B5CF14A;00013B746A07;00013BD3DC75;00013C93FFEB;00013C97C7F9;00013D209177;00013D70229B;00013E0E22E0;00013E259B9D;00013EAB2CBA;00013EF52B12;00013FA9DE87;00013FCA7F7B;000140423537;000140F1F622;0001418E0549;00014207C0E0;0001427EF16A;000142E6A54B;0001437171B2;000143F18213;0001445D82D6;000144BFBFCD;000144D82F72;000145565A54;000145E3CC17;0001465445DF;000146E8D78A;0001475DAEFE;000148134B3C;00014826D0B7;000148967AF4;00014941323F;000149F2BA7A;00014A0DDDCA;00014A255687;00014A84C8F5;00014B44EC6B;00014B48B479;00014BD17DF7;00014C210F1B;00014CBF0F60;00014CD6881D;00014CFC1290;00014D67D0C7;00014E15A240;00014E9BFC84;00014F5CF037;0001500E94E2;000150308CBE;000150BDFE81;0001512E7849;000151EEE54D;000151F90F60;0001523C954D;000152F82799;0001533A44A1;00015372249A;000153EBE031;0001546310BB;000154CAC49C;000155559103;000155D5A164;00015641A227;000156681731;000156C0A394;000157261FF7;000157B391BA;000158240B82;000158E47886;000158EEA299;000159322886;000159EDBAD2;00015A4BE46D;00015A73CEB6;00015AED8A4D;00015B550BE4;00015BCC7AA8;00015C812E1D;00015D0CD60E;00015DAD755D;00015E2F0EDD;00015E337A22;00015E6FCB7B;00015F101B61;00015F1486A6;00015FAB1D92;00015FFDCCC5;000160A56558;0001612E05F1;000161759C78;0001622F1343;000162EFC8F4;00016319D50B;000163CDEAAE;000163E58B28;0001643B615E;000164579397;0001648421BE;000164D7A5B4;000164EE10E0;00016501B2FE;000165533C1E;000165E9D30A;00016642D02A;000166AA51C1;00016721C085;000167D673FA;000168621BEB;00016902BB3A;0001696BC425;00016A15293A;00016A24A3B1;00016A8A5236;00016AC6A38F;00016B68D251;00016BE2472A;00016BF29001;00016C0F63A3;00016C64E0EE;00016C6C2CDF;00016D0144F5;00016DC2851A;00016E6CD268;00016EDE2FF6;00016F531E87;00016FFEB8E5;0001704F3B34;000170D38AE0;00017192C313;000171A66531;000171F7EE51;0001725617EC;000172AF150C;0001731696A3;0001738E0567;00017442B8DC;000174CE60CD;0001756F001C;000175E57C9D;000176798885;000176A9CD04;0001771CBD77;0001778E1B05;000178378D63;00017898EC05;000179425E63;000179E815C2;00017A479724;00017A536D07;00017A72D689;00017AA57862;00017B06D704;00017B5F4477;00017B90B68B;00017C141447;00017CBD795C;00017D29AF83;00017D439E65;00017D574083;00017DA8C9A3;00017E05EB64;00017E5EE884;00017EC66A1B;00017F3DD8DF;00017FF28C54;0001807E3445;0001811ED394;0001813B05CD;000181A85E59;000182149480;0001829E1E21;000182B161ED;000182E941E6;000183382F45;000183C241B5;000184838CBF;000184E1B65A;0001853FDFF5;000185A58E7A;000186393917;000186AD2060;00018702F696;00018796D0AE;000187C5D017;000188664793;000189064EF8;000189BFC5C3;000189D367E1;00018A24F101;00018AC71FC3;00018B201CE3;00018BCA20D9;00018C8A947A;00018CA00B50;00018D45C1E7;00018DBFB301;00018DF9EDB9;00018DFF6150;00018EA013DA;00018EB924BD;00018F3281B4;00018FAED64E;00019035388F;000190D6895C;00019138144A;000191B468E4;0001925A1F7B;000192D41095;000192F99B08;000193115427;00019336DE9A;000193F7523B;000194A273F4;000194E7BCF6;0001950950F7;000195422BD2;0001957C80F0;000195F5C2ED;00019628F785;00019667E385;0001967F83FF;000196D348E0;0001974D8635;000197C4B526;00019859CD3C;000198BC2376;000199281114;0001999E8D95;00019A083E0D;00019A9B14E6;00019B1EF04B;00019B4131D5;00019B4D07B8;00019BB6B830;00019C226D5C;00019C784392;00019CDC0346;00019D06D520;00019DC78AD1;00019E3D9C12;00019EA9E37F;00019F289EB9;00019F508902;00019F9E8E3D;00019FD76918;0001A011BE36;0001A08B0033;0001A0BE34CB;0001A0FAF42F;0001A1151C34;0001A1835FE8;0001A1F0B874;0001A2235A4D;0001A29A893E;0001A2B15644;0001A33ADFE5;0001A3E6E2BB;0001A47AAE1A;0001A4FC479A;0001A54CC9E9;0001A5D2CF75;0001A5FCDB8C;0001A64BC8EB;0001A670C992;0001A69A4E0B;0001A6C94D74;0001A6FABF88;0001A7844058;0001A834DBB0;0001A8A1231D;0001A91FDE57;0001A9944260;0001A9EF8F9F;0001AA85B971;0001AADEA97F;0001AB7C2EB4;0001ABDDB9A2;0001AC1C1756;0001AC6AAA83;0001AD141CE1;0001AD88F455;0001AE19DDEE;0001AEBB0B6A;0001AF5F5A4F;0001AFDA471F;0001B0416889;0001B0E29605;0001B12EAC3D;0001B190372B;0001B1E361FE;0001B1E554A1;0001B21FA9BF;0001B2C0FA8C;0001B32BB2EE;0001B3D860A2;0001B46FB05E;0001B491445F;0001B4CA1F3A;0001B5047458;0001B57DB655;0001B5B0EAED;0001B62AA684;0001B69ED829;0001B71D5A39;0001B72CD4B0;0001B7E354D1;0001B7EAA0C2;0001B87D535E;0001B916BA04;0001B97C3062;0001B9CB1DC1;0001BA2D73FB;0001BAB7866B;0001BB7A08E8;0001BC2E1E8B;0001BC8F7D2D;0001BCC47079;0001BCD7B445;0001BCE1FCCA;0001BD1C846E;0001BDDDC493;0001BDE38836;0001BE4FCFA3;0001BEA0B926;0001BEABE26D;0001BEF9E7A8;0001BF32C283;0001BF6D17A1;0001BFE6599E;0001C0198E36;0001C0D77F2E;0001C17AF605;0001C18B2A37;0001C1B8C7EA;0001C2278DDA;0001C28F1E04;0001C317BE9D;0001C3BCD9DB;0001C41E387D;0001C4317C49;0001C4C5F86D;0001C56BAFCC;0001C58697C6;0001C5B169A0;0001C5E06909;0001C6549AAE;0001C6D7F86A;0001C6E44B77;0001C7A56BB8;0001C8479A7A;0001C84D5E1D;0001C8B9A58A;0001C90A8F0D;0001C9ACBDCF;0001C9FAC30A;0001CA90ECDC;0001CAE9DCEA;0001CB87621F;0001CBE8ED0D;0001CC274AC1;0001CC75DDEE;0001CD1F504C;0001CD9427C0;0001CE251159;0001CEC63ED5;0001CF6A8DBA;0001CFE57A8A;0001D04C9BF4;0001D0EDC970;0001D139DFA8;0001D19B6A96;0001D1EE9569;0001D1F0880C;0001D22ADD2A;0001D234649D;0001D2CE51DF;0001D3460790;0001D37EE26B;0001D3B93789;0001D4327986;0001D465AE1E;0001D4E20658;0001D4F8D35E;0001D5AFA689;0001D632D79D;0001D6D54843;0001D75AABC0;0001D819E78D;0001D86FBDC3;0001D897A80C;0001D8F0346F;0001D9999984;0001DA232325;0001DA783032;0001DA93182C;0001DAAED2BF;0001DB04716B;0001DB972407;0001DBFFC57F;0001DC78EBDA;0001DCED1D7F;0001DD96C2B9;0001DE030A26;0001DE81C560;0001DE95D314;0001DEE3D84F;0001DF7A0221;0001DFD2F22F;0001E0707764;0001E0D20252;0001E1106006;0001E15EF333;0001E2086591;0001E27D3D05;0001E30E269E;0001E3AF541A;0001E453A2FF;0001E4CE8FCF;0001E535B139;0001E5D6DEB5;0001E622F4ED;0001E6847FDB;0001E6D7AAAE;0001E781E384;0001E79A8C26;0001E806B458;0001E84E1A76;0001E8DB8C39;0001E94C0601;0001E9E097AC;0001EA556F20;0001EB0B0B5E;0001EB1E90D9;0001EB8E3B16;0001EC38F261;0001ECEA7A9C;0001ED059DEC;0001ED1D16A9;0001ED7C8917;0001EE3CAC8D;0001EE758768;0001EEAFDC86;0001EEFE6FB3;0001EF439F57;0001EFAFC789;0001EFF72DA7;0001F092A186;0001F1024BC3;0001F1760F47;0001F1CBE57D;0001F2114C4C;0001F27465A0;0001F295238C;0001F2A02E13;0001F31FA6A0;0001F3422E61;0001F367A279;0001F3C2E2D7;0001F456AE36;0001F4D069CD;0001F5479A57;0001F5AF4E38;0001F63A1A9F;0001F6BA2B00;0001F7262BC3;0001F7BCC2AF;0001F84F9988;0001F89D28F3;0001F92A9AB6;0001F99B147E;0001FA2FA629;0001FAA47D9D;0001FB5A19DB;0001FB6D9F56;0001FBDD4993;0001FC8800DE;0001FD398919;0001FD54AC69;0001FD6C2526;0001FDCB9794;0001FE8BBB0A;0001FEC495E5;0001FEFEEB03;0001FF4D7E30;0001FF92ADD4;0001FFFED606;000200463C24;000200E1B003;000201515A40;000201C51DC4;0002021AF3FA;000202605AC9;000202C3741D;000203757F07;00020435EC0B;000204F81FC8;0002055B391C;0002056D9869;0002057604E4;000205993AB0;000205FC5404;000206687C36;000206AFE254;000207198059;000207A6F21C;000208176BE4;000208D7D8E8;000208E202FB;0002092588E8;000209E11B34;000209EF3751;00020A8302B0;00020AFCBE47;00020B73EED1;00020BFE475B;00020C77D8BD;00020C93D07E;00020C9C3CF9;00020CE2E018;00020D6BA996;00020E2DDD42;00020E8AA57B;00020F36FFDC;00020FF72352;000210AE9A30;000210C1DFD2;000211394E96;0002118282C1;000211CDCB61;000211F33F79;0002124E7FD7;000212E24B36;000212E61344;0002136EDCC2;000213BE6DE6;0002145C6E2B;00021473E6E8;00021481252B;0002153405E3;000215F1C63B;000216ABC2F2;000216E9B360;0002171D1DDE;0002172A59A6;00021751A4E7;0002180EA604;000218341A1C;0002188F5A7A;0002192325D9;0002199CE170;00021A1411FA;00021A7BC5DB;00021B069242;00021B86A2A3;00021BF2A366;00021C893A52;00021D1C112B;00021DDE3CCD;00021E6BAE90;00021EDC2858;00021F70BA03;00021FE59177;0002209B2DB5;000220AEB330;0002211E5D6D;000221C914B8;0002227A9CF3;00022295C043;000222AD3900;0002230CAB6E;000223CCCEE4;00022405A9BF;0002243FFEDD;0002248E920A;000224D3C1AE;0002253FE9E0;000225874FFE;00022622C3DD;000226926E1A;00022706319E;0002275C07D4;000227A16EA3;0002280487F7;000228BE3888;0002297B532B;000229F02A9F;00022A2E1B0D;00022A61858B;00022A6EC153;00022A912FEF;00022B08E5AB;00022B139250;00022B390668;00022B9446C6;00022C281225;00022CA1CDBC;00022D18FE46;00022D80B227;00022E0B7E8E;00022E8B8EEF;00022EF78FB2;00022F8E269E;00023020FD77;00023022A7D2;000230B01995;00023120935D;000231B52508;00023229FC7C;000232DF98BA;000232F31E35;00023362C872;0002340D7FBD;000234BF07F8;000234DA2B48;000234F1A405;000235511673;0002361139E9;0002361501F7;0002369DCB75;000236ED5C99;0002378B5CDE;000237A2D59B;0002382866B8;000238889CA9;000239482007;000239FE7240;00023A2DA59D;00023A649563;00023A8FCA43;00023B4AD26A;00023BAAC980;00023C248517;00023C9BB5A1;00023D036982;00023D8E35E9;00023E0E464A;00023E7A470D;00023EDC8404;00023EF4F3A9;00023F5E91AE;00023FEC0371;0002405C7D39;000240F10EE4;00024165E658;0002421B8296;0002422F0811;0002429EB24E;000243496999;000243FAF1D4;000244161524;0002442D8DE1;0002448D004F;0002454D23C5;00024585FEA0;000245C053BE;0002460EE6EB;00024654168F;000246C03EC1;00024707A4DF;000247A318BE;00024812C2FB;00024886867F;000248DC5CB5;00024921C384;00024984DCD8;000249A59AC4;000249B0A54B;000249BF61F6;00024A3F7257;00024ABD50B8;00024B6641C9;00024C1DA935;00024CAB1AF8;00024D1B94C0;00024DDC01C4;00024DE62BD7;00024E29B1C4;00024EE54410;00024EF3602D;00024FA9E04E;000250239BE5;0002509ACC6F;0002512524F9;0002519EB65B;000251BAAE1C;000251C31A97;00025209BDB6;000252928734;00025354BAE0;000253B18319;0002545DDD7A;0002551E00F0;000255D577CE;000255E8BD70;000256602C34;000256A9605F;000256F4A8FF;0002571A1D17;000257755D75;0002580928D4;0002580CF0E2;00025895BA60;000258E54B84;000259834BC9;0002599AC486;000259A802C9;00025A5AE381;00025B18A3D9;00025BD2A090;00025C1090FE;00025C43FB7C;00025C513744;00025C639691;00025C6C030C;00025C8F38D8;00025CE6FE00;00025D746FC3;00025DE4E98B;00025EA5568F;00025EAF80A2;00025EF3068F;00025FAE98DB;00025FBCB4F8;00025FC7DE3F;0002604199D6;000260A91B6D;000261208A31;000261D53DA6;00026260E597;0002630184E6;0002635A8206;000263D9DA18;0002649B2522;000264F39295;0002655C340D;0002659DC588;00026627D7F8;0002663FB8FA;0002664EE523;000266A41EA0;0002670674DA;0002679FDB80;000267F8610D;0002683A36B1;000268DF51EF;0002694A8567;000269EDEDF3;00026A1A7C1A;00026A6D2B4D;00026AAC7AC6;00026AC01CE4;00026B11A604;00026B9A469D;00026BF87038;00026C5FF1CF;00026CD76093;00026D8C1408;00026E17BBF9;00026EB85B48;00026F4507E1;00026F7CE7DA;00026FD5743D;00027093AE47;00027119B3D3;00027143BFEA;000272041406;000272536711;0002726B4813;0002732CD33A;00027338A91D;000273893473;000273F2E4EB;0002747FED86;00027494528C;0002752AE978;000275323569;0002753EFA0F;000275AB3036;000275F2C6BD;0002765A4854;000276D1B718;000277866A8D;00027812127E;000278B2B1CD;00027954E08F;000279E8B448;00027A5264C0;00027A90A31B;00027B071F9C;00027B819F00;00027C3480FE;00027CEB5429;00027D03352B;00027DB20C70;00027E0745ED;00027E5461B9;00027EC327A9;00027F4A973F;00027FA3945F;0002804CF803;000280FB02E9;000281A467FE;00028219568F;000282411A73;00028254BC91;000282A645B1;0002831411B9;0002836D0ED9;0002841712CF;000284D78670;000284ECFD46;00028592B3DD;0002860CA4F7;00028646DFAF;0002864C5346;000286ED05D0;0002870616B3;0002877F73AA;000287FBC844;000288822A85;000289237B52;000289850640;00028A015ADA;00028AA71171;00028B21028B;00028B468CFE;00028B5E461D;00028B7A064E;00028BF578CE;00028C297B31;00028C2C255D;00028CCD51DC;00028D1BE509;00028D3C4194;00028D68BC47;00028DA19722;00028DDBEC40;00028E552E3D;00028E8862D5;00028F2B4D42;00028F967817;00028FC6BC96;000290196BC9;0002909CE141;000290F71FEC;00029152763B;000291F75A87;0002921F1E6B;0002922E4A94;00029289A0E3;000292AEA18A;0002935AA460;000293EFBC76;000294922D1C;000294A02E7D;000294B7CEF7;000294F715F7;000294FAB4D5;0002955D0B0F;00029575935D;000295AE6E38;000295E8C356;000296620553;0002969539EB;000296FAD463;0002978FF41F;000297E0766E;000298745086;000298FC9E0E;0002990A9F6F;00029965F5BE;000299855F40;000299EB0DC5;00029A7ED924;00029AB6B91D;00029AE34744;00029B14F857;00029B53D1F7;00029B7D5670;00029BE706E8;00029C195D5C;00029C71CACF;00029D1B2E73;00029D7684C2;00029DF77042;00029E304B1D;00029E6AA03B;00029EE3E238;00029F1716D0;00029F5602D0;00029F5D4EC1;00029F9AB405;00029FD9FB05;0002A05129F6;0002A0ACF1E8;0002A0C1C29C;0002A1820F96;0002A1918A0D;0002A19CAEB6;0002A19CB3F3;0002A20A7FFB;0002A2529401;0002A2FC065F;0002A3030F36;0002A3539185;0002A3D21395;0002A48893B6;0002A549B3F7;0002A559FCCE;0002A5B97EDB;0002A5F259B6;0002A62CAED4;0002A6A5F0D1;0002A6D92569;0002A7181169;0002A7924EBE;0002A7E824F4;0002A83AD427;0002A8F1A752;0002A909DD9A;0002A97CCE0D;0002A9D9EFCE;0002A9E0E842;0002AA9F224C;0002AAB9112E;0002AB22C1A6;0002AB295F18;0002AB40FF92;0002ABD3B22E;0002ABE2DE57;0002ACA4697E;0002ACDC4977;0002ACDFED5A;0002AD358C06;0002ADA31D93;0002ADDBF86E;0002AE164D8C;0002AE8F8F89;0002AEC2C421;0002AF01B021;0002AF7BED76;0002AFD1C3AC;0002B02472DF;0002B0DB460A;0002B0F37C52;0002B1666CC5;0002B1C38E86;0002B1CA86FA;0002B288C104;0002B2A2AFE6;0002B30C605E;0002B312FDD0;0002B32A9E4A;0002B3BD50E6;0002B3CC7D0F;0002B48E0836;0002B4C5E82F;0002B4C98C12;0002B51F2ABE;0002B58CBC4B;0002B5C59726;0002B5FFEC44;0002B6792E41;0002B6AC62D9;0002B6DC9FE6;0002B715D9EF;0002B79E2777;0002B8095AEF;0002B818369B;0002B83468D4;0002B8D4B8BA;0002B8F4223C;0002B96B512D;0002B97599B2;0002B9E1CFD9;0002BA9B46A4;0002BB24C774;0002BB3EB656;0002BB9E37B8;0002BC21AD30;0002BC9C2C94;0002BCD3F5D3;0002BD337735;0002BDBBB5E0;0002BE455575;0002BE7E3050;0002BEB8856E;0002BF31C76B;0002BF64FC03;0002C0178958;0002C0889E19;0002C10212F2;0002C19DAA0C;0002C223AF98;0002C280D159;0002C2E65FB8;0002C33BDD03;0002C3FCB6D9;0002C42E28ED;0002C4E79FB8;0002C5000F5D;0002C5C05C57;0002C61A9B02;0002C6AD71DB;0002C7161353;0002C72AE407;0002C76A3380;0002C79D29F2;0002C7DEBB6D;0002C82DA24D;0002C8667D28;0002C8A0D246;0002C91A1443;0002C94D48DB;0002C9C70472;0002CA131021;0002CAD45B2B;0002CB4DD004;0002CBA27C52;0002CC4B6D63;0002CCA5AC0E;0002CD63AB51;0002CDFA423D;0002CE25F896;0002CE42CC38;0002CE7E8736;0002CE90A993;0002CE9D6E39;0002CF46E097;0002CF5209DE;0002D01354E8;0002D04505FB;0002D0D9821F;0002D19A37D0;0002D224266C;0002D25D0147;0002D2975665;0002D3109862;0002D343CCFA;0002D3808C5E;0002D43EC668;0002D4A65692;0002D546A07B;0002D5AF6C4D;0002D6239DF2;0002D63F5885;0002D658FDF2;0002D66006C9;0002D7228946;0002D78CB498;0002D7F66510;0002D870E474;0002D8F0E162;0002D9743F1E;0002D9CE7DC9;0002DA82936C;0002DAF3A82D;0002DBAA284E;0002DC3DF3AD;0002DC567BFB;0002DC8F56D6;0002DCC9ABF4;0002DD42EDF1;0002DD762289;0002DE190CF6;0002DE35E098;0002DEBB4415;0002DF60FB74;0002DFE42C88;0002E0414E49;0002E0A6C4A7;0002E0E85622;0002E16362B4;0002E19F1DB2;0002E21BF448;0002E24C38C7;0002E28B8840;0002E3399326;0002E3991488;0002E407DA78;0002E442621C;0002E4CAA0C7;0002E5386CCF;0002E593F8BA;0002E5AC8108;0002E5E55BE3;0002E61FB101;0002E698F2FE;0002E6CC2796;0002E7487FD0;0002E7ADF62E;0002E7B0B20E;0002E8249957;0002E8B9157B;0002E94733F2;0002E986836B;0002EA05DB7D;0002EA4D7204;0002EB0B7147;0002EBB128A6;0002EC03D7D9;0002EC7CFE34;0002EC844A25;0002ECEDFA9D;0002ED417E93;0002EDD549F2;0002EE3E15C4;0002EE68E79E;0002EEA221A7;0002EEBAEB44;0002EEF3C61F;0002EF2E1B3D;0002EFA75D3A;0002EFDA91D2;0002F040B3F1;0002F09DD5B2;0002F0A4DE89;0002F153B5CE;0002F1D7138A;0002F277C614;0002F2A45195;0002F2CDD60E;0002F2D81E93;0002F36AD12F;0002F3E3F78A;0002F44C9902;0002F4F0018E;0002F5AF39C1;0002F617BEED;0002F69DC479;0002F73E7703;0002F777B10C;0002F7D01E7F;0002F81F14EB;0002F8B4EF88;0002F8EDCA63;0002F9281F81;0002F9A1617E;0002F9D49616;0002FA4E51AD;0002FA9ED3FC;0002FB066426;0002FBA6B40C;0002FC0812AE;0002FC1C2062;0002FCC7116A;0002FD17872B;0002FD2662D7;0002FD9A4A20;0002FE2E1DD9;0002FE32891E;0002FE7C45B5;0002FE833E29;0002FF078DD5;0002FF0E2B47;0002FF5D18A6;0002FFADA3FC;0002FFC20902;0002FFCD3249;0003001B24D1;00030053FFAC;0003008E54CA;0003010796C7;0003013ACB5F;000301B486F6;000302050945;0003026C996F;0003030CE955;0003036E47F7;0003038255AB;0003042D46B3;0003047DBC74;0003048C9820;000305007F69;000305945322;00030598BE67;000305E27AFE;000305E97372;0003066DC31E;000306746090;000306C34DEF;00030713D945;000307283E4B;000307336792;00030747683B;000307B3AFA8;00030804992B;0003082053BE;0003086E58F9;0003090482CB;0003095D72D9;000309FAF80E;00030A5C82FC;00030A9AE0B0;00030AE973DD;00030B92E63B;00030C07BDAF;00030C98A748;00030D39D4C4;00030DDE23A9;00030E591079;00030EC031E3;00030F615F5F;00030FAD7597;0003100F0085;000310622B58;0003110C642E;000311250CD0;000311913502;000311D89B20;000312278200;00031297FBC8;0003132C8D73;000313A164E7;000314570125;0003146A86A0;000314DA30DD;00031584E828;000316367063;0003165193B3;000316690C70;000316C87EDE;00031788A254;000317C17D2F;000317FBD24D;0003184A657A;0003188F951E;000318FBBD50;00031943236E;000319D2B1D1;00031A566CA2;00031A7EBFCB;00031AD49601;00031B19FCD0;00031B7D1624;00031B9799CB;00031C1A4E53;00031C5DD440;00031CDAC0C0;00031D17B840;00031D8F6DFC;00031E248C73;00031E7391C1;00031EC9FDFD;00031F43B994;00031FBAEA1E;000320229DFF;000320AD6A66;0003212D7AC7;000321997B8A;0003222D55A2;000322E3D5C3;000323495226;000323D6C3E9;000324473DB1;000324DBCF5C;00032550A6D0;00032606430E;00032619C889;0003268972C6;000327342A11;000327E5B24C;00032800D59C;000328184E59;00032877C0C7;00032937E43D;00032970BF18;000329AB1436;000329F9A763;00032A3ED707;00032AAAFF39;00032AF26557;00032B81F3BA;00032C05AE8B;00032C2E01B4;00032C83D7EA;00032CC93EB9;00032D2C580D;00032DB7FFFE;00032DF4F77E;00032E0B121D;00032E3898B1;00032E67CC0E;00032E9EBBD4;00032EB19153;00032EF7EC12;00032F8D0A89;00032FDC0FD7;000330327C13;000330AC37AA;000331236834;0003318B1C15;00033215E87C;00033295F8DD;00033301F9A0;00033395D3B8;0003344C53D9;000335025C00;0003358FCDC3;00033600478B;00033694D936;00033709B0AA;000337BF4CE8;000337D2D263;000338427CA0;000338ED33EB;0003399EBC26;000339B9DF76;000339D15833;00033A30CAA1;00033AF0EE17;00033B29C8F2;00033B641E10;00033BB2B13D;00033BF7E0E1;00033C640913;00033CAB6F31;00033D3AFD94;00033DBEB865;00033DE70B8E;00033E3CE1C4;00033E824893;00033EE561E7;00033F18967F;00033FD90383;0003409B3740;000340FE5094;00034189F885;000341C6F005;000341DD0AA4;000341F551B5;000342B78572;000343009923;000343C2C4C5;000344503688;000344C0B050;000345811D54;0003458B4767;000345CECD54;0003468A5FA0;0003474AB3BC;000347598F68;000347D34AFF;0003484A7B89;000348D4D413;0003494E6575;0003496A5D36;00034972C9B1;000349B96CD0;00034A42364E;00034B0469FA;00034B613233;00034C0D8C94;00034CCDB00A;00034D8526E8;00034D986C8A;00034E0FDB4E;00034E590F79;00034EA45819;00034EC9CC31;00034F250C8F;00034F7B78CB;00034F86C27E;000350134318;000350BFD6A7;0003515DD6EC;000351754FA9;000351F23C29;000352A51CE1;00035362DD39;0003541CD9F0;000354948FAC;000354C7FA2A;000354D535F2;000355081BB5;0003552B77B0;000355362455;000355CB42CC;0003561A481A;00035670B456;000356EA6FED;00035761A077;000357C95458;0003585420BF;000358D43120;0003594031E3;000359D40BFB;000359DF3542;00035A2CC4AD;00035ABA3670;00035B2AB038;00035BBF41E3;00035C341957;00035CE9B595;00035CFD3B10;00035D6CE54D;00035E179C98;00035EC924D3;00035EE44823;00035EFBC0E0;00035F5B334E;0003601B56C4;00036054319F;0003608E86BD;000360DD19EA;00036122498E;0003618E71C0;000361D5D7DE;000362656641;000362E92112;00036311743B;000363674A71;000363ACB140;0003640FCA94;000364CCF9F9;0003658A149C;000365FEEC10;00036676A1CC;000366AA0C4A;000366B74812;00036777212D;0003682B7A77;000368A33033;000368ADDCD8;00036942FB4F;00036992009D;000369E86CD9;00036A622870;00036AD958FA;00036B410CDB;00036BCBD942;00036C4BE9A3;00036CB7EA66;00036D4BC47E;00036D56EDC5;00036DC08BCA;00036E4DFD8D;00036EBE7755;00036F530900;00036FC7E074;0003707D7CB2;00037091022D;00037100AC6A;000371AB63B5;0003725CEBF0;000372780F40;0003728F87FD;000372EEFA6B;000373AF1DE1;000373E7F8BC;000374224DDA;00037470E107;000374B610AB;0003752238DD;000375699EFB;000375F92D5E;00037668D79B;000376DC9B1F;000377327155;00037777D824;000377DAF178;0003788CFC62;0003794D6966;00037A0F9D23;00037A72B677;00037A7884AC;00037B02DD36;00037B7A92F2;00037B853F97;00037BFEFB2E;00037C762BB8;00037CDDDF99;00037D68AC00;00037DE8BC61;00037E54BD24;00037EE8973C;00037EF3C083;00037FB5EC25;000380435DE8;000380B3D7B0;00038148695B;000381BD40CF;00038272DD0D;000382866288;000382F60CC5;000383A0C410;000384524C4B;0003846D6F9B;00038484E858;000384E45AC6;000385A47E3C;000385DD5917;00038617AE35;000386664162;000386AB7106;000387179938;0003875EFF56;000387EE8DB9;0003885E37F6;000388D1FB7A;00038927D1B0;0003896D387F;000389D051D3;00038A87E79A;00038B0A9C22;00038B4E220F;00038BEA79DE;00038C522DBF;00038C9C2768;00038D08FC6F;00038DBB9B01;00038E355698;00038EAC8722;00038F143B03;00038F9F076A;0003901F17CB;0003908B188E;0003911EF2A6;0003912A1BED;0003912BC648;000391B9380B;000391F212E6;0003922C6804;000392A5AA01;000392D8DE99;0003935799D3;000393EAA5D2;000393F31E08;00039456DDBC;000394ACB3F2;0003950EF0E9;0003954192C2;00039559C90A;000395A8BF76;000395B51283;0003962F4FD8;000396C35BC0;0003977CD28B;000397E557B7;00039834AAC2;000398517E64;000398BED6F0;000399277868;000399CAEF3F;00039A61862B;00039A6749CE;00039AD3913B;00039B247ABE;00039B4AEFC8;00039B98F503;00039C2F1ED5;00039C880EE3;00039D259418;00039D871F06;00039DC57CBA;00039E140FE7;00039EBD8245;00039F3259B9;00039FC34352;0003A06470CE;0003A108BFB3;0003A183AC83;0003A1EACDED;0003A28BFB69;0003A2D811A1;0003A3399C8F;0003A38CC762;0003A4370038;0003A44FA8DA;0003A48CC98E;0003A52D6A5D;0003A5BADC20;0003A5F3B6FB;0003A62E0C19;0003A6A74E16;0003A6DA82AE;0003A7593DE8;0003A8198AE2;0003A8461909;0003A8B45CBD;0003A8F63261;0003A96D6152;0003A99F1265;0003AA588930;0003AAAEF56C;0003AB4F3F55;0003AB5637C9;0003AC17C2F0;0003AC920045;0003AD092F36;0003AD180AE2;0003AD823634;0003ADADEC8D;0003ADC622D5;0003AE4D926B;0003AE6737D8;0003AEA1C4A9;0003AF0E0C16;0003AF5EF599;0003AFC13290;0003B04AD225;0003B083AD00;0003B0BE021E;0003B137441B;0003B16A78B3;0003B1BB6236;0003B24574A6;0003B2CF4EAE;0003B3860A04;0003B3E195EF;0003B4130803;0003B4963917;0003B5423BED;0003B5EB9F91;0003B69A52A3;0003B74343B4;0003B76B2DFD;0003B7F37B85;0003B84C78A5;0003B89CEE66;0003B8FE4D08;0003B9B76B1B;0003BA24C3A7;0003BA804F92;0003BAD2FEC5;0003BB3AE434;0003BBA72BA1;0003BBF81524;0003BC8BEF3C;0003BCE73C7B;0003BD201756;0003BD5A6C74;0003BDD3AE71;0003BE06E309;0003BEC4D401;0003BF1D4AFA;0003BF728477;0003C0128BDC;0003C0960154;0003C0D36698;0003C176DD6F;0003C1E7F230;0003C223AD2E;0003C278597C;0003C31BC208;0003C36E713B;0003C37C729C;0003C4032D42;0003C4963941;0003C499DD24;0003C4B7CFD1;0003C4BF1BC2;0003C57FF598;0003C62510D6;0003C65CD37B;0003C6C91AE8;0003C71A046B;0003C7782E06;0003C7C63341;0003C85C5D13;0003C8B54D21;0003C952D256;0003C9B45D44;0003C9F2BAF8;0003CA414E25;0003CAEAC083;0003CB5F97F7;0003CBF08190;0003CC91AF0C;0003CD35FDF1;0003CDB0EAC1;0003CE180C2B;0003CEB939A7;0003CF054FDF;0003CF66DACD;0003CFBA05A0;0003CFBBF843;0003CFF64D61;0003D0AF084E;0003D0CFA44F;0003D12C0667;0003D1D9EB05;0003D212C5E0;0003D24D1AFE;0003D2C65CFB;0003D2F99193;0003D329CEA0;0003D3A850B0;0003D3B29935;0003D440B7AC;0003D465B853;0003D4F8C452;0003D506E06F;0003D5347E22;0003D5D99960;0003D63F27BF;0003D68FB315;0003D6C12529;0003D726D3AE;0003D7CC8B0D;0003D7F18BB4;0003D8443AE7;0003D8610E89;0003D8CC395E;0003D90E5666;0003D948DE0A;0003D9B0C379;0003DA1D0AE6;0003DA6DF469;0003DAD03160;0003DB1E369B;0003DB571176;0003DB916694;0003DC0AA891;0003DC3DDD29;0003DCBA3563;0003DCD26BAB;0003DD667793;0003DDD22CBF;0003DE02713E;0003DE1741F2;0003DEBC263E;0003DF0B7949;0003DF589515;0003DFC3C88D;0003E05793EC;0003E061DC71;0003E10DDF47;0003E1BDA032;0003E228CB07;0003E246BDB4;0003E246C2F1;0003E24CCA94;0003E2C34715;0003E2CBBF4B;0003E332C09F;0003E36B9B7A;0003E3A5F098;0003E41F3295;0003E452672D;0003E504F482;0003E54D0888;0003E550A766;0003E5FC41C4;0003E6AB1909;0003E6DDBAE2;0003E76AC37D;0003E7E3E9D8;0003E837AEB9;0003E879845D;0003E8E7C811;0003E9A6021B;0003EA31591D;0003EAF29942;0003EB1799E9;0003EB59B6F1;0003EBC10B28;0003EC14D009;0003EC8B4C8A;0003ECB0BA1D;0003ED5A7CB6 +STORE_CATALOG_ID ; 13332 \ No newline at end of file diff --git a/SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/ME3_MSG.txt b/SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/ME3_MSG.txt new file mode 100644 index 000000000..08e7fa336 --- /dev/null +++ b/SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/ME3_MSG.txt @@ -0,0 +1,21 @@ +MSG_1_endDate ; 10:03:2013 +MSG_1_image ; FullTeamPromo.dds +MSG_1_message ; Check your Challenges window now! +MSG_1_message_de ; Ã?berprüfe jetzt dein Herausforderungen-Fenster! +MSG_1_message_es ; ¡Comprueba ya tu ventana de desafíos! +MSG_1_message_fr ; Consultez dès maintenant la fenêtre de défis ! +MSG_1_message_it ; Controlla subito la finestra Sfide! +MSG_1_message_ja ; ã?ã?£ã?¬ã?³ã?¸ç?»é¢ã??ä»?ã?ぐ確認ã?ã??ã?! +MSG_1_message_pl ; Sprawdź okno WyzwaÅ? już teraz! +MSG_1_message_ru ; Ð?еÑ?ейдиÑ?е в окно испÑ?Ñ?аний! +MSG_1_priority ; 201 +MSG_1_title ; New Weekend Challenge Available +MSG_1_title_de ; Neue Wochenendherausforderung verfügbar +MSG_1_title_es ; Disponible nuevo desafío de fin de semana +MSG_1_title_fr ; Un nouveau défi du week-end est disponible +MSG_1_title_it ; Nuova sfida Weekend disponibile +MSG_1_title_ja ; ã?¦ã?£ã?¼ã?¯ã?¨ã?³ã?? ã?ã?£ã?¬ã?³ã?¸ã?å?©ç?¨å¯è?½ +MSG_1_title_pl ; Nowe Wyzwanie Weekendowe dostÄ?pne +MSG_1_title_ru ; Ð?осÑ?Ñ?пно новое испÑ?Ñ?ание вÑ?Ñ?одного дня +MSG_1_trackingId ; 150 +MSG_1_type ; 8 \ No newline at end of file diff --git a/WebServers/HTTPServer/HttpProcessor.cs b/WebServers/HTTPServer/HttpProcessor.cs index b9c77dba6..3184cc1ba 100644 --- a/WebServers/HTTPServer/HttpProcessor.cs +++ b/WebServers/HTTPServer/HttpProcessor.cs @@ -38,6 +38,7 @@ using WebAPIService.HTS; using WebAPIService.ILoveSony; using Newtonsoft.Json; +using WebAPIService.CCPGames; namespace HTTPServer { @@ -84,6 +85,11 @@ public partial class HttpProcessor "samples.hdk.scee.net", }; + + private readonly static List CCPGamesDomains = new() { + //"dust.ccpgamescdn.com", + "dust514.online" + }; private readonly static List ILoveSonyDomains = new() { "www.myresistance.net", }; @@ -317,8 +323,31 @@ public void HandleClient(TcpClient? tcpClient, ushort ListenerPort) { default: + #region Dust 514 dcrest + //CCPGamesDomains.Contains(Host) || + if (Host.Contains("26004") //Check for Dust514 specific Port!! + && !string.IsNullOrEmpty(Method)) + { + LoggerAccessor.LogInfo($"[HTTP] - {clientip}:{clientport} Identified a Dust514 method : {absolutepath}"); + + string? res = null; + if (request.GetDataStream != null) + { + using MemoryStream postdata = new(); + request.GetDataStream.CopyTo(postdata); + res = new Dust514Class(request.Method, absolutepath, HTTPServerConfiguration.APIStaticFolder).ProcessRequest(postdata.ToArray(), request.GetContentType(), request.Headers, false); + postdata.Flush(); + } + if (string.IsNullOrEmpty(res)) + response = HttpBuilder.InternalServerError(); + else + response = HttpResponse.Send(res, "text/plain"); + } + + #endregion + #region Outso OHS API - if ((Host == "stats.outso-srv1.com" + else if ((Host == "stats.outso-srv1.com" || Host == "www.outso-srv1.com") && request.GetDataStream != null && (absolutepath.Contains("/ohs_") || diff --git a/WebServers/HTTPServer/Program.cs b/WebServers/HTTPServer/Program.cs index 8e284c508..7a82557b9 100644 --- a/WebServers/HTTPServer/Program.cs +++ b/WebServers/HTTPServer/Program.cs @@ -42,7 +42,7 @@ public static class HTTPServerConfiguration public static bool EnableImageUpscale { get; set; } = false; public static Dictionary? MimeTypes { get; set; } = HTTPProcessor._mimeTypes; public static Dictionary? DateTimeOffset { get; set; } - public static List? Ports { get; set; } = new() { 80, 3074, 9090, 10010, 33000 }; + public static List? Ports { get; set; } = new() { 80, 3074, 9090, 10010, 26004, 33000 }; public static List? RedirectRules { get; set; } public static List? BannedIPs { get; set; } From 17dca64bb05d227e6afb5a8b0b7aec04283f0ecf Mon Sep 17 00:00:00 2001 From: JumpSuit <26616362+Jump-Suit@users.noreply.github.com> Date: Thu, 7 Nov 2024 06:24:36 -0600 Subject: [PATCH 02/16] Update Blaze with BF4 Config request --- .../MultiSocks/Blaze/BlazeClass.cs | 2 +- .../Blaze/Components/Util/UtilComponent.cs | 48 ++++++++++++++----- 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/SpecializedServers/MultiSocks/Blaze/BlazeClass.cs b/SpecializedServers/MultiSocks/Blaze/BlazeClass.cs index c7bb3f45d..42f23885f 100644 --- a/SpecializedServers/MultiSocks/Blaze/BlazeClass.cs +++ b/SpecializedServers/MultiSocks/Blaze/BlazeClass.cs @@ -26,7 +26,7 @@ public BlazeClass(CancellationToken cancellationToken) // Create Blaze Redirector servers redirector = Blaze3.CreateBlazeServer(domain, new IPEndPoint(IPAddress.Any, 42127), SSLCache.GetVulnerableCustomEaCert(domain, "Global Online Studio", true, true).Item3); // Create Main Blaze server - mainBlaze = Blaze3.CreateBlazeServer(domain, new IPEndPoint(IPAddress.Any, 33152), SSLCache.GetVulnerableCustomEaCert(domain, "Global Online Studio").Item3, false); + mainBlaze = Blaze3.CreateBlazeServer(domain, new IPEndPoint(IPAddress.Any, 33152), SSLCache.GetVulnerableCustomEaCert(domain, "Global Online Studio", false, false).Item3, false); redirector.AddComponent(); diff --git a/SpecializedServers/MultiSocks/Blaze/Components/Util/UtilComponent.cs b/SpecializedServers/MultiSocks/Blaze/Components/Util/UtilComponent.cs index b35509626..6a5e48ba9 100644 --- a/SpecializedServers/MultiSocks/Blaze/Components/Util/UtilComponent.cs +++ b/SpecializedServers/MultiSocks/Blaze/Components/Util/UtilComponent.cs @@ -209,18 +209,40 @@ public override Task FetchClientConfigAsync(FetchClientConf LoggerAccessor.LogInfo($"[Blaze] - Util: mConfigSection : {request.mConfigSection}"); string ME3ClientConfig = Directory.GetCurrentDirectory() + "/static/EA/ME3_CONFIG/"; + string BF4OBClientConfig = Directory.GetCurrentDirectory() + "/static/EA/BF4_OB/"; Directory.CreateDirectory(ME3ClientConfig); - string filePathFull = ME3ClientConfig + request.mConfigSection + ".txt"; + Directory.CreateDirectory(BF4OBClientConfig); + + string fileBF4PathFull = BF4OBClientConfig + request.mConfigSection + ".txt"; + string fileME3PathFull = ME3ClientConfig + request.mConfigSection + ".txt"; var fileClientConfigDictionary = new SortedDictionary(); switch(request.mConfigSection) { + + case "IdentityParams": + if (File.Exists(fileBF4PathFull)) + { + string[] fileConfig = File.ReadAllLines(fileBF4PathFull); + + for (int i = 0; i < fileConfig.Length; i++) + { + string[] parts = fileConfig[i].Split(';'); + + fileClientConfigDictionary.Add(parts[0].Trim(), parts[1].Trim()); + } + } + else + { + LoggerAccessor.LogWarn($"File not found! Path expected: {fileME3PathFull}"); + } + break; case "ME3_DATA": - if (File.Exists(filePathFull)) + if (File.Exists(fileME3PathFull)) { - string[] fileConfig = File.ReadAllLines(filePathFull); + string[] fileConfig = File.ReadAllLines(fileME3PathFull); for (int i = 0; i < fileConfig.Length; i++) { @@ -231,14 +253,14 @@ public override Task FetchClientConfigAsync(FetchClientConf } else { - LoggerAccessor.LogWarn($"File not found! Path expected: {filePathFull}"); + LoggerAccessor.LogWarn($"File not found! Path expected: {fileME3PathFull}"); } break; case "ME3_MSG": - if (File.Exists(filePathFull)) + if (File.Exists(fileME3PathFull)) { - string[] fileConfig = File.ReadAllLines(filePathFull); + string[] fileConfig = File.ReadAllLines(fileME3PathFull); for (int i = 0; i < fileConfig.Length; i++) { @@ -249,14 +271,14 @@ public override Task FetchClientConfigAsync(FetchClientConf } else { - LoggerAccessor.LogWarn($"File not found! Path expected: {filePathFull}"); + LoggerAccessor.LogWarn($"File not found! Path expected: {fileME3PathFull}"); } break; case "ME3_ENT": - if (File.Exists(filePathFull)) + if (File.Exists(fileME3PathFull)) { - string[] fileConfig = File.ReadAllLines(filePathFull); + string[] fileConfig = File.ReadAllLines(fileME3PathFull); for (int i = 0; i < fileConfig.Length; i++) { @@ -271,21 +293,21 @@ public override Task FetchClientConfigAsync(FetchClientConf } else { - LoggerAccessor.LogWarn($"File not found! Path expected: {filePathFull}"); + LoggerAccessor.LogWarn($"File not found! Path expected: {fileME3PathFull}"); } break; case "ME3_DIME": - if (File.Exists(filePathFull)) + if (File.Exists(fileME3PathFull)) { - string fileConfig = File.ReadAllText(filePathFull); + string fileConfig = File.ReadAllText(fileME3PathFull); fileClientConfigDictionary.Add("Config", fileConfig); } else { - LoggerAccessor.LogWarn($"File not found! Path expected: {filePathFull}"); + LoggerAccessor.LogWarn($"File not found! Path expected: {fileME3PathFull}"); } break; From 7da0cafe3d7b4a7683f5c70427250e1737415273 Mon Sep 17 00:00:00 2001 From: JumpSuit <26616362+Jump-Suit@users.noreply.github.com> Date: Thu, 7 Nov 2024 06:26:09 -0600 Subject: [PATCH 03/16] HTTPProcessor API update Update Dust514 crest API Add Ubisoft's Build DB API --- .../WebAPIService/CCPGames/Dust514Class.cs | 199 +++++++++++++++--- .../BuildDBPullServiceHandler.cs | 171 +++++++++++++++ .../UBISOFT/BuildAPI/SoapBuildAPIClass.cs | 89 ++++++++ WebServers/HTTPServer/HttpProcessor.cs | 23 ++ 4 files changed, 454 insertions(+), 28 deletions(-) create mode 100644 BackendServices/AuxiliaryServices/WebAPIService/UBISOFT/BuildAPI/BuildDBPullService/BuildDBPullServiceHandler.cs create mode 100644 BackendServices/AuxiliaryServices/WebAPIService/UBISOFT/BuildAPI/SoapBuildAPIClass.cs diff --git a/BackendServices/AuxiliaryServices/WebAPIService/CCPGames/Dust514Class.cs b/BackendServices/AuxiliaryServices/WebAPIService/CCPGames/Dust514Class.cs index f6ae202d7..11ee67fee 100644 --- a/BackendServices/AuxiliaryServices/WebAPIService/CCPGames/Dust514Class.cs +++ b/BackendServices/AuxiliaryServices/WebAPIService/CCPGames/Dust514Class.cs @@ -27,6 +27,12 @@ public string ProcessRequest(byte[] PostData, string ContentType, List x.Key.Equals("Accept")).Value; + +#if DEBUG + LoggerAccessor.LogWarn(contentTypeValue); +#endif + //string GlobalState.charaId = string.Empty; //bool isLoggedIn = false; @@ -36,7 +42,11 @@ public string ProcessRequest(byte[] PostData, string ContentType, List buildDbRequests = new List() + { "GetCurrentLauncherVersion", "GetConsoleOwner", + "GetProjectDetailWithMacValidation", "GetFilteredBuildVersionsWithMacValidation", + "GetProjectsWithMacValidation", "GetFilteredBuildVersionsWithMacValidation"}; + + + if (buildDbRequests.Contains(innerRequestName)) + { + switch (innerRequestName) { + case "GetCurrentLauncherVersion": + { + + Console.WriteLine($"GetCurrentLauncherVersion: TRIGGERED!"); + + return @" + + + + 2.10.1 + /BuildDBPullService.asmx + 4 + 4 + + +"; + } + + default: + { + + Console.WriteLine($"GetCurrentLauncherVersion: FAILEd!"); + return @" + + + + 2.10.1 + /BuildDBPullService.asmx + 4 + 4 + + +"; + } + + } + + + //Console.WriteLine($"ADLogin: {adLogin}"); + //Console.WriteLine($"Name: {name}"); + } + else + { + Console.WriteLine("No GetConsoleOwnerResult found."); + } + + /* + // Get the GetConsoleOwner element from the SOAP body + var resultElement = xdoc.Descendants(soap + "Body").FirstOrDefault(); + + if (buildDbRequests.Contains(resultElement.Name.ToString())) + { + // Extract the ADLogin and Name elements + string adLogin = resultElement.Element("ADLogin")?.Value; + string name = resultElement.Element("Name")?.Value; + + Console.WriteLine($"ADLogin: {adLogin}"); + Console.WriteLine($"Name: {name}"); + } + else + { + Console.WriteLine("No GetConsoleOwnerResult found."); + } + + */ + + + return @" + + + + 2.10.2 + /BuildDBPullService.asmx + 4 + 4 + + +"; + + + } + + + public static string getVersion(byte[] PostData, string ContentType) { + + + return @" + + + + + hensley.edwin + Hensley Edwin + + + +"; + } + + public static string getConsoleOwner(byte[] PostData, string ContentType) + { + + + return @" + + + + + hensley.edwin + Hensley Edwin + + + +"; + } + } +} diff --git a/BackendServices/AuxiliaryServices/WebAPIService/UBISOFT/BuildAPI/SoapBuildAPIClass.cs b/BackendServices/AuxiliaryServices/WebAPIService/UBISOFT/BuildAPI/SoapBuildAPIClass.cs new file mode 100644 index 000000000..723f64cac --- /dev/null +++ b/BackendServices/AuxiliaryServices/WebAPIService/UBISOFT/BuildAPI/SoapBuildAPIClass.cs @@ -0,0 +1,89 @@ +using CustomLogger; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WebAPIService.OUWF; +using WebAPIService.UBISOFT.BuildAPI.BuildDBPullService; + +namespace WebAPIService.UBISOFT.BuildAPI +{ + + public class SoapBuildAPIClass : IDisposable + { + string workpath; + string absolutepath; + string method; + private bool disposedValue; + + public SoapBuildAPIClass(string method, string absolutepath, string workpath) + { + this.workpath = workpath; + this.absolutepath = absolutepath; + this.method = method; + } + + public string ProcessRequest(byte[] PostData, string ContentType) + { + if (string.IsNullOrEmpty(absolutepath)) + return null; + + switch (method) + { + case "POST": + switch (absolutepath) + { + + case "/BuildDBPullService.asmx": + return BuildDBPullServiceHandler.buildDBRequestParser(PostData, ContentType); + default: + { + LoggerAccessor.LogError($"[OuWF] - Unhandled server request discovered: {absolutepath} | DETAILS: \n{Encoding.UTF8.GetString(PostData)}"); + } + break; + } + break; + default: + { + LoggerAccessor.LogError($"[OuWF] - Method unhandled {method}"); + } + break; + } + + return null; + } + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + absolutepath = string.Empty; + method = string.Empty; + workpath = string.Empty; + } + + // TODO: libérer les ressources non managées (objets non managés) et substituer le finaliseur + // TODO: affecter aux grands champs une valeur null + disposedValue = true; + } + } + + // // TODO: substituer le finaliseur uniquement si 'Dispose(bool disposing)' a du code pour libérer les ressources non managées + // ~HERMESClass() + // { + // // Ne changez pas ce code. Placez le code de nettoyage dans la méthode 'Dispose(bool disposing)' + // Dispose(disposing: false); + // } + + public void Dispose() + { + // Ne changez pas ce code. Placez le code de nettoyage dans la méthode 'Dispose(bool disposing)' + Dispose(disposing: true); + GC.SuppressFinalize(this); + } + } +} diff --git a/WebServers/HTTPServer/HttpProcessor.cs b/WebServers/HTTPServer/HttpProcessor.cs index 8bacda016..6340e80b7 100644 --- a/WebServers/HTTPServer/HttpProcessor.cs +++ b/WebServers/HTTPServer/HttpProcessor.cs @@ -40,6 +40,7 @@ using WebAPIService.ILoveSony; using WebAPIService.CCPGames; using WebAPIService.DEMANGLER; +using WebAPIService.UBISOFT.BuildAPI; namespace HTTPServer { @@ -413,6 +414,28 @@ public void HandleClient(TcpClient? tcpClient, ushort ListenerPort) } #endregion + #region Ubisoft Build API + else if (Host == "builddatabasepullapi" + && request.GetDataStream != null + && !string.IsNullOrEmpty(Method) + && request.GetContentType().StartsWith("application/soap+xml")) + { + LoggerAccessor.LogInfo($"[HTTP] - {clientip} Identified a Ubisoft Build API method : {absolutepath}"); + + string? res = null; + using (MemoryStream postdata = new()) + { + request.GetDataStream.CopyTo(postdata); + res = new SoapBuildAPIClass(Method, absolutepath, HTTPServerConfiguration.HTTPStaticFolder).ProcessRequest(postdata.ToArray(), request.GetContentType()); + postdata.Flush(); + } + if (string.IsNullOrEmpty(res)) + response = HttpBuilder.InternalServerError(); + else + response = HttpResponse.Send(res, "text/xml"); + } + #endregion + #region VEEMEE API else if ((Host == "away.veemee.com" || Host == "home.veemee.com" From 518214f445bcd607913f9fdee3723b435b122512 Mon Sep 17 00:00:00 2001 From: JumpSuit <26616362+Jump-Suit@users.noreply.github.com> Date: Thu, 7 Nov 2024 06:29:10 -0600 Subject: [PATCH 04/16] Oopsie --- .../CCPGames/Helpers/NPTicketSample.cs | 134 ------------------ 1 file changed, 134 deletions(-) delete mode 100644 BackendServices/AuxiliaryServices/WebAPIService/CCPGames/Helpers/NPTicketSample.cs diff --git a/BackendServices/AuxiliaryServices/WebAPIService/CCPGames/Helpers/NPTicketSample.cs b/BackendServices/AuxiliaryServices/WebAPIService/CCPGames/Helpers/NPTicketSample.cs deleted file mode 100644 index f67030374..000000000 --- a/BackendServices/AuxiliaryServices/WebAPIService/CCPGames/Helpers/NPTicketSample.cs +++ /dev/null @@ -1,134 +0,0 @@ -using CustomLogger; -using HttpMultipartParser; -using System.Text; -using System.IO; -using System; -using NetworkLibrary.Extension; -using HashLib; - -namespace WebAPIService.HTS.Helpers -{ - public class MyResistanceEula - { - public static string RequestNPTicket(byte[] PostData, string boundary) - { - string userid = string.Empty; - string sessionid = string.Empty; - string resultString = string.Empty; - string region = string.Empty; - byte[] ticketData = null; - - if (PostData != null) - { - using (MemoryStream copyStream = new MemoryStream(PostData)) - { - foreach (var file in MultipartFormDataParser.Parse(copyStream, boundary).Files) - { - using (Stream filedata = file.Data) - { - filedata.Position = 0; - - // Find the number of bytes in the stream - int contentLength = (int)filedata.Length; - - // Create a byte array - byte[] buffer = new byte[contentLength]; - - // Read the contents of the memory stream into the byte array - filedata.Read(buffer, 0, contentLength); - - if (file.FileName == "ticket.bin") - ticketData = buffer; - - filedata.Flush(); - } - } - - copyStream.Flush(); - } - } - - if (ticketData != null) - { - #region Region - // Extract part of the byte array from the specific index - byte[] ticketRegion = new byte[] { 0x00, 0x00, 0x00, 0x00 }; - Array.Copy(ticketData, 0x78, ticketRegion, 0, 4); - #endregion - - #region Domain - // Extract part of the byte array from the specific index - byte[] ticketDomain = new byte[] { 0x00, 0x00, 0x00, 0x00 }; - Array.Copy(ticketData, 0x80, ticketDomain, 0, 4); - #endregion - - #region ServiceId - byte serviceIdLen = (byte)ticketData.GetValue(0x87); - // Extract part of the byte array from the specific index - byte[] servId = new byte[serviceIdLen]; - Array.Copy(ticketData, 0x88, servId, 0, serviceIdLen); - #endregion - - // Extract the desired portion of the binary data - byte[] userOnlineId = new byte[0x63 - 0x54 + 1]; - - // Copy it - Array.Copy(ticketData, 0x54, userOnlineId, 0, userOnlineId.Length); - - // Convert 0x00 bytes to 0x20 so we pad as space. - for (int i = 0; i < userOnlineId.Length; i++) - { - if (userOnlineId[i] == 0x00) - userOnlineId[i] = 0x20; - } - - if (OtherExtensions.FindBytePattern(ticketData, new byte[] { 0x52, 0x50, 0x43, 0x4E }, 184) != -1) - { - LoggerAccessor.LogInfo($"[HTS] : User {Encoding.ASCII.GetString(userOnlineId).Replace("H", string.Empty)} logged in and is on RPCN"); - - // Convert the modified data to a string - resultString = Encoding.ASCII.GetString(userOnlineId) + "RPCN"; - - // Calculate the MD5 hash of the result - string hash = NetHasher.ComputeMD5String(Encoding.ASCII.GetBytes(resultString + "HtTeStSamPLe@$!")); - - // Trim the hash to a specific length - hash = hash.Substring(0, 10); - - // Append the trimmed hash to the result - resultString += hash; - } - else - { - LoggerAccessor.LogInfo($"[HTS] : {Encoding.ASCII.GetString(userOnlineId).Replace("H", string.Empty)} logged in and is on PSN"); - - // Convert the modified data to a string - resultString = Encoding.ASCII.GetString(userOnlineId); - - // Calculate the MD5 hash of the result - string hash = NetHasher.ComputeMD5String(Encoding.ASCII.GetBytes(resultString + "HtTeStSamPLe@$!")); - - // Trim the hash to a specific length - hash = hash.Substring(0, 14); - - // Append the trimmed hash to the result - resultString += hash; - } - - return $@" - {Encoding.UTF8.GetString(userOnlineId)} - - - - - {Encoding.UTF8.GetString(servId)} - {Encoding.UTF8.GetString(ticketRegion)} - - - "; - } - - return null; - } - } -} From 8babb4a5fdac1c6bc32285decd372524c838ec75 Mon Sep 17 00:00:00 2001 From: JumpSuit <26616362+Jump-Suit@users.noreply.github.com> Date: Sat, 16 Nov 2024 16:32:31 -0600 Subject: [PATCH 05/16] Small Fixes --- .../WebAPIService/CCPGames/Dust514Class.cs | 28 ++++---- .../BuildDBPullServiceHandler.cs | 33 ++------- .../WebAPIService/WebAPIService.csproj | 1 - .../EmotionEngine.Emulator/Ps2Float.cs | 1 - .../Horizon/SERVER/Medius/MAPS.cs | 72 ++++++++++++++++--- .../{ME3DATA - Copy.txt => ME3DATA_PC.txt} | 0 6 files changed, 83 insertions(+), 52 deletions(-) rename SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/{ME3DATA - Copy.txt => ME3DATA_PC.txt} (100%) diff --git a/BackendServices/AuxiliaryServices/WebAPIService/CCPGames/Dust514Class.cs b/BackendServices/AuxiliaryServices/WebAPIService/CCPGames/Dust514Class.cs index 11ee67fee..f97496418 100644 --- a/BackendServices/AuxiliaryServices/WebAPIService/CCPGames/Dust514Class.cs +++ b/BackendServices/AuxiliaryServices/WebAPIService/CCPGames/Dust514Class.cs @@ -60,7 +60,7 @@ public string ProcessRequest(byte[] PostData, string ContentType, List - diff --git a/BackendServices/CastleLibrary/EmotionEngine.Emulator/Ps2Float.cs b/BackendServices/CastleLibrary/EmotionEngine.Emulator/Ps2Float.cs index a04b7bc67..2c608d511 100644 --- a/BackendServices/CastleLibrary/EmotionEngine.Emulator/Ps2Float.cs +++ b/BackendServices/CastleLibrary/EmotionEngine.Emulator/Ps2Float.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Specialized; namespace EmotionEngine.Emulator { diff --git a/SpecializedServers/Horizon/SERVER/Medius/MAPS.cs b/SpecializedServers/Horizon/SERVER/Medius/MAPS.cs index 1888bec75..e89635f46 100644 --- a/SpecializedServers/Horizon/SERVER/Medius/MAPS.cs +++ b/SpecializedServers/Horizon/SERVER/Medius/MAPS.cs @@ -84,8 +84,13 @@ protected override async Task ProcessMessage(BaseScertMessage message, IChannel } data.ClientObject = MediusClass.Manager.GetClientByAccessToken(clientConnectTcp.AccessToken, clientConnectTcp.AppId); - if (data.ClientObject == null) - data.ClientObject = MediusClass.Manager.GetClientBySessionKey(clientConnectTcp.SessionKey, clientConnectTcp.AppId); + // If booth are null, it means MAS client wants a new object. + if (!string.IsNullOrEmpty(clientConnectTcp.AccessToken) && !string.IsNullOrEmpty(clientConnectTcp.SessionKey)) + { + data.ClientObject = MediusClass.Manager.GetClientByAccessToken(clientConnectTcp.AccessToken, clientConnectTcp.AppId); + if (data.ClientObject == null) + data.ClientObject = MediusClass.Manager.GetClientBySessionKey(clientConnectTcp.SessionKey, clientConnectTcp.AppId); + } if (data.ClientObject != null) LoggerAccessor.LogInfo($"[MAPS] - Client Connected {clientChannel.RemoteAddress}!"); @@ -95,6 +100,7 @@ protected override async Task ProcessMessage(BaseScertMessage message, IChannel data.ClientObject = new(scertClient.MediusVersion ?? 0) { + MediusVersion = scertClient.MediusVersion ?? 0, ApplicationId = clientConnectTcp.AppId }; data.ClientObject.OnConnected(); @@ -187,15 +193,13 @@ protected virtual void ProcessMediusPluginMessage(BaseMediusPluginMessage messag case NetMessageHello netMessageHello: { - /* - data.ClientObject?.Queue(new NetMAPSHelloMessage() - { - m_success = false, - m_isOnline = false, - m_availableFactions = new byte[3] { 1, 2, 3 } - }); - */ + //MAGDevBuild3 = 1725 + //MAG BCET70016 v1.3 = 7002 + + + var ProtoBytesReversed = ReverseBytesUInt(1725); + var BuildNumber = ReverseBytesUInt(0); data.ClientObject.Queue(new NetMessageTypeProtocolInfo() { protocolInfo = EndianUtils.ReverseUint(1725), //1725 //1958 @@ -209,6 +213,25 @@ protected virtual void ProcessMediusPluginMessage(BaseMediusPluginMessage messag case NetMessageTypeProtocolInfo protocolInfo: { + byte[] availFactions = new byte[] { 0b00000111, 0, 0, 0 }; //= new byte[4]; + + //0b11100000 + //availFactions[0] = 0; + //availFactions[1] = 0; + //availFactions[2] = 0; + //availFactions[3] = 31; + + data.ClientObject.Queue(new NetMAPSHelloMessage() + { + m_success = true, + m_isOnline = true, + m_availableFactions = availFactions + + }); + + + + //Time DateTime time = DateTime.Now; long timeBS = time.Ticks >> 1; @@ -283,6 +306,35 @@ public static string ShiftString(string t) return t[1..] + t[..1]; } + public static ulong ReverseBytesULong(ulong value) + { + return ((value & 0x000000FFU) << 24 | (value & 0x0000FF00U) << 8 | + (value & 0x00FF0000U) >> 8 | (value & 0xFF000000U) >> 24); + } + + public static uint ReverseBytesUInt(uint value) + { + return ((value & 0x000000FFU) << 24 | (value & 0x0000FF00U) << 8 | + (value & 0x00FF0000U) >> 8 | (value & 0xFF000000U) >> 24); + } + public static int ReverseBytesInt(int value) + { + return (int)((value & 0x000000FFU) << 24 | (value & 0x0000FF00U) << 8 | + (value & 0x00FF0000U) >> 8 | (value & 0xFF000000U) >> 24); + } + + #region ReverseBytes16 + /// + /// Reverses UInt16 + /// + /// + /// + public static ushort ReverseBytes16(ushort nValue) + { + return (ushort)((ushort)((nValue >> 8)) | (nValue << 8)); + } + #endregion + public byte[] BitShift(byte[] sequence, int length) { // Check if the length is valid diff --git a/SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/ME3DATA - Copy.txt b/SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/ME3DATA_PC.txt similarity index 100% rename from SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/ME3DATA - Copy.txt rename to SpecializedServers/MultiSocks/static/EA/ME3_CONFIG/ME3DATA_PC.txt From 23d66b44c12beac8beb74d0c6ca4806017a53271 Mon Sep 17 00:00:00 2001 From: JumpSuit <26616362+Jump-Suit@users.noreply.github.com> Date: Sat, 16 Nov 2024 16:34:03 -0600 Subject: [PATCH 06/16] Update BuildDBPullServiceHandler.cs --- .../BuildAPI/BuildDBPullService/BuildDBPullServiceHandler.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BackendServices/AuxiliaryServices/WebAPIService/UBISOFT/BuildAPI/BuildDBPullService/BuildDBPullServiceHandler.cs b/BackendServices/AuxiliaryServices/WebAPIService/UBISOFT/BuildAPI/BuildDBPullService/BuildDBPullServiceHandler.cs index f4951b11a..af0cd8a9c 100644 --- a/BackendServices/AuxiliaryServices/WebAPIService/UBISOFT/BuildAPI/BuildDBPullService/BuildDBPullServiceHandler.cs +++ b/BackendServices/AuxiliaryServices/WebAPIService/UBISOFT/BuildAPI/BuildDBPullService/BuildDBPullServiceHandler.cs @@ -40,7 +40,7 @@ public static string buildDBRequestParser(byte[] PostData, string ContentType) case "GetCurrentLauncherVersion": { - Console.WriteLine($"GetCurrentLauncherVersion: TRIGGERED!"); + LoggerAccessor.LogInfo($"GetCurrentLauncherVersion: TRIGGERED!"); return @" Date: Thu, 21 Nov 2024 19:32:47 +0100 Subject: [PATCH 07/16] [Ps2Float] - Implements 100% accurate Mul operations. All the credits belongs to TellowKrinkle from the PCSX2 team. --- .../EmotionEngine.Emulator/BoothMultiplier.cs | 73 ++++++++++++ .../EmotionEngine.Emulator/Ps2Float.cs | 108 +++--------------- 2 files changed, 86 insertions(+), 95 deletions(-) create mode 100644 BackendServices/CastleLibrary/EmotionEngine.Emulator/BoothMultiplier.cs diff --git a/BackendServices/CastleLibrary/EmotionEngine.Emulator/BoothMultiplier.cs b/BackendServices/CastleLibrary/EmotionEngine.Emulator/BoothMultiplier.cs new file mode 100644 index 000000000..18bfddfc0 --- /dev/null +++ b/BackendServices/CastleLibrary/EmotionEngine.Emulator/BoothMultiplier.cs @@ -0,0 +1,73 @@ +namespace EmotionEngine.Emulator +{ + // From the PCSX2 Team (TellowKrinkle) + public class BoothMultiplier + { + private struct BoothRecode + { + public uint data; + public uint negate; + }; + + private struct AddResult + { + public uint lo; + public uint hi; + }; + + private static BoothRecode Booth(uint a, uint b, uint bit) + { + uint test = (bit != 0 ? b >> (int)(bit * 2 - 1) : b << 1) & 7; + a <<= (int)(bit * 2); + a += (test == 3 || test == 4) ? a : 0; + uint neg = (test >= 4 && test <= 6) ? ~0u : 0; + uint pos = 1u << (int)(bit * 2); + a ^= neg & (uint)-pos; + a &= (test >= 1 && test <= 6) ? ~0u : 0; + return new BoothRecode { data = a, negate = neg & pos }; + } + + // Add 3 rows of bits in parallel + private static AddResult Add3(uint a, uint b, uint c) + { + uint u = a ^ b; + return new AddResult { lo = u ^ c, hi = ((u & c) | (a & b)) << 1 }; + } + + public static ulong MulMantissa(uint a, uint b) + { + ulong full = (ulong)a * (ulong)b; + BoothRecode b0 = Booth(a, b, 0); + BoothRecode b1 = Booth(a, b, 1); + BoothRecode b2 = Booth(a, b, 2); + BoothRecode b3 = Booth(a, b, 3); + BoothRecode b4 = Booth(a, b, 4); + BoothRecode b5 = Booth(a, b, 5); + BoothRecode b6 = Booth(a, b, 6); + BoothRecode b7 = Booth(a, b, 7); + + // First cycle + AddResult t0 = Add3(b1.data, b2.data, b3.data); + AddResult t1 = Add3(b4.data & ~0x7ffu, b5.data & ~0xfffu, b6.data); + // A few adds get skipped, squeeze them back in + t1.hi |= b6.negate | (b5.data & 0x800); + b7.data |= (b5.data & 0x400) + b5.negate; + + // Second cycle + AddResult t2 = Add3(b0.data, t0.lo, t0.hi); + AddResult t3 = Add3(b7.data, t1.lo, t1.hi); + + // Third cycle + AddResult t4 = Add3(t2.hi, t3.lo, t3.hi); + + // Fourth cycle + AddResult t5 = Add3(t2.lo, t4.lo, t4.hi); + + // Discard bits and sum + t5.hi += b7.negate; + t5.lo &= ~0x7fffu; + t5.hi &= ~0x7fffu; + return full - (((t5.lo + t5.hi) ^ full) & 0x8000); + } + } +} diff --git a/BackendServices/CastleLibrary/EmotionEngine.Emulator/Ps2Float.cs b/BackendServices/CastleLibrary/EmotionEngine.Emulator/Ps2Float.cs index a04b7bc67..755395497 100644 --- a/BackendServices/CastleLibrary/EmotionEngine.Emulator/Ps2Float.cs +++ b/BackendServices/CastleLibrary/EmotionEngine.Emulator/Ps2Float.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Specialized; namespace EmotionEngine.Emulator { @@ -257,110 +256,29 @@ private Ps2Float DoAdd(Ps2Float other) return new Ps2Float((uint)man & 0x80000000 | (uint)rawExp << 23 | ((uint)absMan & 0x7FFFFF)).RoundTowardsZero(); } - // Rounding can be slightly off: (PS2/IEEE754: 0x3F800040 * 0x3F800020 = 0x3F800060 | SoftFloat: 0x3F800040 * 0x3F800020 = 0x3F80005F). private Ps2Float DoMul(Ps2Float other) { + byte selfExponent = Exponent; + byte otherExponent = other.Exponent; uint selfMantissa = Mantissa | 0x800000; uint otherMantissa = other.Mantissa | 0x800000; - int resExponent = Exponent + other.Exponent - BIAS; - - Ps2Float result = new Ps2Float(0) { Sign = DetermineMultiplicationDivisionOperationSign(this, other) }; + uint sign = (AsUInt32() ^ other.AsUInt32()) & 0x80000000; - if (resExponent > 255) - return result.Sign ? Min() : Max(); - else if (resExponent < 0) - return new Ps2Float(result.Sign, 0, 0); - - uint testImprecision = otherMantissa ^ ((otherMantissa >> 4) & 0x800); // For some reason, 0x808000 loses a bit and 0x800800 loses a bit, but 0x808800 does not - ulong res = 0; - ulong mask = Convert.ToUInt64("0xFFFFFFFFFFFFFFFF", 16); // Uses a booth and wallace tree approach to Multiplication. - - result.Exponent = (byte)resExponent; + int resExponent = selfExponent + otherExponent - 127; + uint resMantissa = (uint)(BoothMultiplier.MulMantissa(selfMantissa, otherMantissa) >> 23); - otherMantissa <<= 1; - - uint[] part = new uint[13]; // Partial products - uint[] bit = new uint[13]; // More partial products. 0 or 1. - - for (int i = 0; i <= 12; i++, otherMantissa >>= 2) + if (resMantissa > 0xffffff) { - uint test = otherMantissa & 7; - if (test == 0 || test == 7) - { - part[i] = 0; - bit[i] = 0; - } - else if (test == 3) - { - part[i] = (selfMantissa << 1); - bit[i] = 0; - } - else if (test == 4) - { - part[i] = ~(selfMantissa << 1); - bit[i] = 1; - } - else if (test < 4) - { - part[i] = selfMantissa; - bit[i] = 0; - } - else - { - part[i] = ~selfMantissa; - bit[i] = 1; - } - } - - for (int i = 0; i <= 12; i++) - { - res += (ulong)(int)part[i] << (i * 2); - res &= mask; - res += bit[i] << (i * 2); + resMantissa >>= 1; + resExponent++; } - result.Mantissa = (uint)(res >> 23); - - if ((testImprecision & 0x000aaa) != 0 && (res & 0x7FFFFF) == 0) - result.Mantissa -= 1; - - if (result.Mantissa > 0) - { - int leadingBitPosition = GetMostSignificantBitPosition(result.Mantissa); - - while (leadingBitPosition != IMPLICIT_LEADING_BIT_POS) - { - if (leadingBitPosition > IMPLICIT_LEADING_BIT_POS) - { - result.Mantissa >>= 1; - - int increasedExponent = result.Exponent + 1; - - if (increasedExponent > 255) - return result.Sign ? Min() : Max(); - - result.Exponent = (byte)increasedExponent; - - leadingBitPosition--; - } - else if (leadingBitPosition < IMPLICIT_LEADING_BIT_POS) - { - result.Mantissa <<= 1; - - int decreasedExponent = result.Exponent - 1; - - if (decreasedExponent <= 0) - return new Ps2Float(result.Sign, 0, 0); - - result.Exponent = (byte)decreasedExponent; - - leadingBitPosition++; - } - } - } + if (resExponent > 255) + return new Ps2Float(sign | MAX_FLOATING_POINT_VALUE); + else if (resExponent <= 0) + return new Ps2Float(sign); - result.Mantissa &= 0x7FFFFF; - return result.RoundTowardsZero(); + return new Ps2Float(sign | (uint)(resExponent << 23) | (resMantissa & 0x7fffff)).RoundTowardsZero(); } // Rounding can be slightly off: (PS2: 0x3F800000 / 0x3F800001 = 0x3F7FFFFF | SoftFloat/IEEE754: 0x3F800000 / 0x3F800001 = 0x3F7FFFFE). From b681af4825411d3ed131e09472fe0ee9ade1b9e3 Mon Sep 17 00:00:00 2001 From: GitHubProUser67 <127040195+GitHubProUser67@users.noreply.github.com> Date: Thu, 21 Nov 2024 19:37:59 +0100 Subject: [PATCH 08/16] Update Ps2Float.cs Uses more constants for fixed values. --- .../EmotionEngine.Emulator/Ps2Float.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/BackendServices/CastleLibrary/EmotionEngine.Emulator/Ps2Float.cs b/BackendServices/CastleLibrary/EmotionEngine.Emulator/Ps2Float.cs index 755395497..0e4a9a669 100644 --- a/BackendServices/CastleLibrary/EmotionEngine.Emulator/Ps2Float.cs +++ b/BackendServices/CastleLibrary/EmotionEngine.Emulator/Ps2Float.cs @@ -105,26 +105,26 @@ public Ps2Float Add(Ps2Float addend) // diff = 25 .. 255 , expt < expd if (expDiff >= 25) { - b = b & 0x80000000; + b = b & SIGNMASK; } // diff = 1 .. 24, expt < expd else if (expDiff > 0) { expDiff = expDiff - 1; - temp = unchecked((int)0xffffffff) << expDiff; + temp = unchecked((int)MIN_FLOATING_POINT_VALUE) << expDiff; b = (uint)(temp & b); } // diff = -255 .. -25, expd < expt else if (expDiff <= -25) { - a = a & 0x80000000; + a = a & SIGNMASK; } // diff = -24 .. -1 , expd < expt else if (expDiff < 0) { expDiff = -expDiff; expDiff = expDiff - 1; - temp = unchecked((int)0xffffffff) << expDiff; + temp = unchecked((int)MIN_FLOATING_POINT_VALUE) << expDiff; a = (uint)(a & temp); } @@ -149,26 +149,26 @@ public Ps2Float Sub(Ps2Float subtrahend) // diff = 25 .. 255 , expt < expd if (expDiff >= 25) { - b = b & 0x80000000; + b = b & SIGNMASK; } // diff = 1 .. 24, expt < expd else if (expDiff > 0) { expDiff = expDiff - 1; - temp = unchecked((int)0xffffffff) << expDiff; + temp = unchecked((int)MIN_FLOATING_POINT_VALUE) << expDiff; b = (uint)(temp & b); } // diff = -255 .. -25, expd < expt else if (expDiff <= -25) { - a = a & 0x80000000; + a = a & SIGNMASK; } // diff = -24 .. -1 , expd < expt else if (expDiff < 0) { expDiff = -expDiff; expDiff = expDiff - 1; - temp = unchecked((int)0xffffffff) << expDiff; + temp = unchecked((int)MIN_FLOATING_POINT_VALUE) << expDiff; a = (uint)(a & temp); } @@ -253,7 +253,7 @@ private Ps2Float DoAdd(Ps2Float other) else if (rawExp <= 0) return new Ps2Float(man < 0, 0, 0); - return new Ps2Float((uint)man & 0x80000000 | (uint)rawExp << 23 | ((uint)absMan & 0x7FFFFF)).RoundTowardsZero(); + return new Ps2Float((uint)man & SIGNMASK | (uint)rawExp << 23 | ((uint)absMan & 0x7FFFFF)).RoundTowardsZero(); } private Ps2Float DoMul(Ps2Float other) @@ -262,7 +262,7 @@ private Ps2Float DoMul(Ps2Float other) byte otherExponent = other.Exponent; uint selfMantissa = Mantissa | 0x800000; uint otherMantissa = other.Mantissa | 0x800000; - uint sign = (AsUInt32() ^ other.AsUInt32()) & 0x80000000; + uint sign = (AsUInt32() ^ other.AsUInt32()) & SIGNMASK; int resExponent = selfExponent + otherExponent - 127; uint resMantissa = (uint)(BoothMultiplier.MulMantissa(selfMantissa, otherMantissa) >> 23); From 4075fc5465fee930b0cab5c6bb45b2c515b8d88f Mon Sep 17 00:00:00 2001 From: JumpSuit <26616362+Jump-Suit@users.noreply.github.com> Date: Tue, 10 Dec 2024 21:05:23 -0600 Subject: [PATCH 09/16] Some Requested Fixes --- .../WebAPIService/CCPGames/Dust514Class.cs | 0 .../BuildDBPullServiceHandler.cs | 0 .../UBISOFT/BuildAPI/SoapBuildAPIClass.cs | 2 +- .../Horizon/SERVER/Medius/MAPS.cs | 66 +-- .../Blaze/Components/Auth/AuthComponent.cs | 10 +- .../Blaze/Components/Util/UtilComponent.cs | 11 +- .../SVO/Games/PS3/MotorstormPR2.cs | 444 ++++++++++++++++++ .../SVO/Games/PS3/SocomConfrontation.cs | 18 +- SpecializedServers/SVO/SVOServer.cs | 5 +- .../HTTPSecureServerLite/HttpsProcessor.cs | 4 +- WebServers/HTTPServer/HttpProcessor.cs | 8 +- 11 files changed, 467 insertions(+), 101 deletions(-) rename {BackendServices/AuxiliaryServices => AuxiliaryServices}/WebAPIService/CCPGames/Dust514Class.cs (100%) rename {BackendServices/AuxiliaryServices => AuxiliaryServices}/WebAPIService/UBISOFT/BuildAPI/BuildDBPullService/BuildDBPullServiceHandler.cs (100%) rename {BackendServices/AuxiliaryServices => AuxiliaryServices}/WebAPIService/UBISOFT/BuildAPI/SoapBuildAPIClass.cs (93%) create mode 100644 SpecializedServers/SVO/Games/PS3/MotorstormPR2.cs diff --git a/BackendServices/AuxiliaryServices/WebAPIService/CCPGames/Dust514Class.cs b/AuxiliaryServices/WebAPIService/CCPGames/Dust514Class.cs similarity index 100% rename from BackendServices/AuxiliaryServices/WebAPIService/CCPGames/Dust514Class.cs rename to AuxiliaryServices/WebAPIService/CCPGames/Dust514Class.cs diff --git a/BackendServices/AuxiliaryServices/WebAPIService/UBISOFT/BuildAPI/BuildDBPullService/BuildDBPullServiceHandler.cs b/AuxiliaryServices/WebAPIService/UBISOFT/BuildAPI/BuildDBPullService/BuildDBPullServiceHandler.cs similarity index 100% rename from BackendServices/AuxiliaryServices/WebAPIService/UBISOFT/BuildAPI/BuildDBPullService/BuildDBPullServiceHandler.cs rename to AuxiliaryServices/WebAPIService/UBISOFT/BuildAPI/BuildDBPullService/BuildDBPullServiceHandler.cs diff --git a/BackendServices/AuxiliaryServices/WebAPIService/UBISOFT/BuildAPI/SoapBuildAPIClass.cs b/AuxiliaryServices/WebAPIService/UBISOFT/BuildAPI/SoapBuildAPIClass.cs similarity index 93% rename from BackendServices/AuxiliaryServices/WebAPIService/UBISOFT/BuildAPI/SoapBuildAPIClass.cs rename to AuxiliaryServices/WebAPIService/UBISOFT/BuildAPI/SoapBuildAPIClass.cs index 723f64cac..7a7365b6f 100644 --- a/BackendServices/AuxiliaryServices/WebAPIService/UBISOFT/BuildAPI/SoapBuildAPIClass.cs +++ b/AuxiliaryServices/WebAPIService/UBISOFT/BuildAPI/SoapBuildAPIClass.cs @@ -40,7 +40,7 @@ public string ProcessRequest(byte[] PostData, string ContentType) return BuildDBPullServiceHandler.buildDBRequestParser(PostData, ContentType); default: { - LoggerAccessor.LogError($"[OuWF] - Unhandled server request discovered: {absolutepath} | DETAILS: \n{Encoding.UTF8.GetString(PostData)}"); + LoggerAccessor.LogError($"[BuildAPI] - Unhandled server request discovered: {absolutepath} | DETAILS: \n{Encoding.UTF8.GetString(PostData)}"); } break; } diff --git a/SpecializedServers/Horizon/SERVER/Medius/MAPS.cs b/SpecializedServers/Horizon/SERVER/Medius/MAPS.cs index e89635f46..3f26bbb3f 100644 --- a/SpecializedServers/Horizon/SERVER/Medius/MAPS.cs +++ b/SpecializedServers/Horizon/SERVER/Medius/MAPS.cs @@ -83,7 +83,6 @@ protected override async Task ProcessMessage(BaseScertMessage message, IChannel } } - data.ClientObject = MediusClass.Manager.GetClientByAccessToken(clientConnectTcp.AccessToken, clientConnectTcp.AppId); // If booth are null, it means MAS client wants a new object. if (!string.IsNullOrEmpty(clientConnectTcp.AccessToken) && !string.IsNullOrEmpty(clientConnectTcp.SessionKey)) { @@ -100,7 +99,6 @@ protected override async Task ProcessMessage(BaseScertMessage message, IChannel data.ClientObject = new(scertClient.MediusVersion ?? 0) { - MediusVersion = scertClient.MediusVersion ?? 0, ApplicationId = clientConnectTcp.AppId }; data.ClientObject.OnConnected(); @@ -196,10 +194,6 @@ protected virtual void ProcessMediusPluginMessage(BaseMediusPluginMessage messag //MAGDevBuild3 = 1725 //MAG BCET70016 v1.3 = 7002 - - - var ProtoBytesReversed = ReverseBytesUInt(1725); - var BuildNumber = ReverseBytesUInt(0); data.ClientObject.Queue(new NetMessageTypeProtocolInfo() { protocolInfo = EndianUtils.ReverseUint(1725), //1725 //1958 @@ -229,17 +223,14 @@ protected virtual void ProcessMediusPluginMessage(BaseMediusPluginMessage messag }); - - - //Time DateTime time = DateTime.Now; long timeBS = time.Ticks >> 1; //bool finBs = true >> 1; //Content string bitshift - string newsBs = ShiftString("Test News"); - string eulaBs = ShiftString("Test Eula"); + //string newsBs = ShiftString("Test News"); + //string eulaBs = ShiftString("Test Eula"); // News/Eula Type bitshifted int newsBS = 0;//Convert.ToInt32(NetMessageNewsEulaResponseContentType.News) >> 1; int eulaBS = 1;//Convert.ToInt32(NetMessageNewsEulaResponseContentType.Eula) >> 1; @@ -300,58 +291,5 @@ protected virtual void ProcessMediusPluginMessage(BaseMediusPluginMessage messag } } } - - public static string ShiftString(string t) - { - return t[1..] + t[..1]; - } - - public static ulong ReverseBytesULong(ulong value) - { - return ((value & 0x000000FFU) << 24 | (value & 0x0000FF00U) << 8 | - (value & 0x00FF0000U) >> 8 | (value & 0xFF000000U) >> 24); - } - - public static uint ReverseBytesUInt(uint value) - { - return ((value & 0x000000FFU) << 24 | (value & 0x0000FF00U) << 8 | - (value & 0x00FF0000U) >> 8 | (value & 0xFF000000U) >> 24); - } - public static int ReverseBytesInt(int value) - { - return (int)((value & 0x000000FFU) << 24 | (value & 0x0000FF00U) << 8 | - (value & 0x00FF0000U) >> 8 | (value & 0xFF000000U) >> 24); - } - - #region ReverseBytes16 - /// - /// Reverses UInt16 - /// - /// - /// - public static ushort ReverseBytes16(ushort nValue) - { - return (ushort)((ushort)((nValue >> 8)) | (nValue << 8)); - } - #endregion - - public byte[] BitShift(byte[] sequence, int length) - { - // Check if the length is valid - if (length <= 0 || length >= 8) - { - LoggerAccessor.LogError("[MAPS] - Invalid shift length. The length must be between 1 and 7."); - return Array.Empty(); - } - - // Perform the bitwise shift operation - byte[] shiftedSequence = new byte[sequence.Length]; - for (int i = 0; i < sequence.Length; i++) - { - shiftedSequence[i] = (byte)(sequence[i] << length); - } - - return shiftedSequence; - } } } diff --git a/SpecializedServers/MultiSocks/Blaze/Components/Auth/AuthComponent.cs b/SpecializedServers/MultiSocks/Blaze/Components/Auth/AuthComponent.cs index 307da40ca..50751aade 100644 --- a/SpecializedServers/MultiSocks/Blaze/Components/Auth/AuthComponent.cs +++ b/SpecializedServers/MultiSocks/Blaze/Components/Auth/AuthComponent.cs @@ -1,15 +1,7 @@ -using Blaze3SDK; -using Blaze3SDK.Blaze.Authentication; -using Blaze3SDK.Blaze.Util; +using Blaze3SDK.Blaze.Authentication; using Blaze3SDK.Components; using BlazeCommon; using CustomLogger; -using MultiSocks.Utils; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace MultiSocks.Blaze.Util { diff --git a/SpecializedServers/MultiSocks/Blaze/Components/Util/UtilComponent.cs b/SpecializedServers/MultiSocks/Blaze/Components/Util/UtilComponent.cs index 6a5e48ba9..a116b02c1 100644 --- a/SpecializedServers/MultiSocks/Blaze/Components/Util/UtilComponent.cs +++ b/SpecializedServers/MultiSocks/Blaze/Components/Util/UtilComponent.cs @@ -1,17 +1,8 @@ -using Blaze3SDK; -using Blaze3SDK.Blaze; +using Blaze3SDK.Blaze; using Blaze3SDK.Blaze.Util; using Blaze3SDK.Components; using BlazeCommon; using CustomLogger; -using MultiSocks.Aries.Messages; -using MultiSocks.Utils; -using Org.BouncyCastle.Asn1.Ocsp; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace MultiSocks.Blaze.Components.Util { diff --git a/SpecializedServers/SVO/Games/PS3/MotorstormPR2.cs b/SpecializedServers/SVO/Games/PS3/MotorstormPR2.cs new file mode 100644 index 000000000..b1205cf8f --- /dev/null +++ b/SpecializedServers/SVO/Games/PS3/MotorstormPR2.cs @@ -0,0 +1,444 @@ +using CustomLogger; +using System.Net; +using System.Text; +using SpaceWizards.HttpListener; +using System.Text.RegularExpressions; +using System.Web; +using HttpListenerRequest = SpaceWizards.HttpListener.HttpListenerRequest; +using HttpListenerResponse = SpaceWizards.HttpListener.HttpListenerResponse; + +namespace SVO.Games.PS3 +{ + public class MotorstormPR2 + { + public static async Task MotorStormPR_SVO(HttpListenerRequest request, HttpListenerResponse response) + { + try + { + /* + if (request.Url == null) + { + response.StatusCode = (int)System.Net.HttpStatusCode.Forbidden; + return; + } + */ + string? method = request.HttpMethod; + + using (response) + { + switch (request.Url.AbsolutePath) + { + #region MotorStorm 2 + case "/MOTORSTORM2PS3_SVML/index.jsp": + { + switch (request.HttpMethod) + { + case "GET": + HttpListenerRequest req = request; + HttpListenerResponse resp = response; + resp.Headers.Set("Content-Type", "text/xml"); + + string clientMac = req.Headers.Get("X-SVOMac"); + string serverMac = SVOProcessor.CalcuateSVOMac(clientMac); + if (string.IsNullOrEmpty(serverMac)) + { + response.StatusCode = (int)HttpStatusCode.Forbidden; + return; + } + else + { + /* + if (!req.HasEntityBody) + { + response.StatusCode = (int)System.Net.HttpStatusCode.Forbidden; + return; + } + */ + resp.Headers.Set("X-SVOMac", serverMac); + + byte[] uriStore = null; + if (SVOServerConfiguration.SVOHTTPSBypass) + { + uriStore = Encoding.UTF8.GetBytes(@" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + " + ); + } + else + { + uriStore = Encoding.UTF8.GetBytes(@" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + " + ); + } + + resp.OutputStream.Write(uriStore); +#if DEBUG + LoggerAccessor.LogInfo($"Start URIStore for Resistance: Fall of Man SENT!"); +#endif + } + break; + } + break; + } + + + case "/MOTORSTORM2PS3_XML/account/SP_Login.jsp": + switch (request.HttpMethod) + { + case "POST": + + string? clientMac = request.Headers.Get("X-SVOMac"); + + string? serverMac = SVOProcessor.CalcuateSVOMac(clientMac); + + if (string.IsNullOrEmpty(serverMac)) + { + response.StatusCode = (int)System.Net.HttpStatusCode.Forbidden; + return; + } + else + { + int appId = Convert.ToInt32(HttpUtility.ParseQueryString(request.Url.Query).Get("applicationID")); + + if (!request.HasEntityBody) + { + response.StatusCode = (int)System.Net.HttpStatusCode.Forbidden; + return; + } + + response.Headers.Set("Content-Type", "text/xml"); + + string s = string.Empty; + + // Get the data from the HTTP stream + using (StreamReader reader = new(request.InputStream, request.ContentEncoding)) + { + // Convert the data to a string and display it on the console. + s = reader.ReadToEnd(); + reader.Close(); + } + + byte[] bytes = Encoding.ASCII.GetBytes(s); + int AcctNameLen = Convert.ToInt32(bytes.GetValue(81)); + + string acctName = s.Substring(82, 32); + + string acctNameREX = Regex.Replace(acctName, @"[^a-zA-Z0-9]+", string.Empty); + + LoggerAccessor.LogInfo($"Logging user {acctNameREX} into SVO...\n"); + + response.Headers.Set("X-SVOMac", serverMac); + + string? sig = HttpUtility.ParseQueryString(request.Url.Query).Get("sig"); + + int accountId = -1; + + string langId = "0"; + + try + { + //if(SVOServerConfiguration.) + + await SVOServerConfiguration.Database.GetAccountByName(acctNameREX, appId).ContinueWith((r) => + { + //Found in database so keep. + langId = request.Url.Query[94..]; + //string? accountName = r.Result.AccountName; + + string accountName = acctNameREX; + accountId = r.Result.AccountId; + }); + } + catch (Exception) + { + langId = request.Url.Query[94..]; + accountId = 0; + } + + response.AddHeader("Set-Cookie", $"LangID={langId}; Path=/"); + response.AppendHeader("Set-Cookie", $"AcctID={accountId}; Path=/"); + response.AppendHeader("Set-Cookie", $"NPCountry=us; Path=/"); + response.AppendHeader("Set-Cookie", $"ClanID=-1; Path=/"); + response.AppendHeader("Set-Cookie", $"AuthKeyTime=03-31-2023 16:03:41; Path=/"); + response.AppendHeader("Set-Cookie", $"NPLang=1; Path=/"); + response.AppendHeader("Set-Cookie", $"ModerateMode=false; Path=/"); + response.AppendHeader("Set-Cookie", $"TimeZone=PST; Path=/"); + response.AppendHeader("Set-Cookie", $"ClanID=-1; Path=/"); + response.AppendHeader("Set-Cookie", $"NPContentRating=201326592; Path=/"); + response.AppendHeader("Set-Cookie", $"AuthKey=nRqnf97f~UaSANLErurJIzq9GXGWqWCADdA3TfqUIVXXisJyMnHsQ34kA&C^0R#&~JULZ7xUOY*rXW85slhQF&P&Eq$7kSB&VBtf`V8rb^BC`53jGCgIT; Path=/"); + response.AppendHeader("Set-Cookie", $"AcctName={acctNameREX}; Path=/"); + response.AppendHeader("Set-Cookie", $"OwnerID=-255; Path=/"); + response.AppendHeader("Set-Cookie", $"Sig={sig}==; Path=/"); + + byte[] sp_Login = Encoding.UTF8.GetBytes("\r\n" + + "\r\n" + + " \r\n" + + " \r\n" + + " 20600\r\n" + + " ACCT_LOGIN_SUCCESS\r\n" + + " \r\n" + + $" {accountId}\r\n" + + " 0\r\n" + + " \r\n" + + ""); + + response.StatusCode = (int)System.Net.HttpStatusCode.OK; + + if (response.OutputStream.CanWrite) + { + try + { + response.ContentLength64 = sp_Login.Length; + response.OutputStream.Write(sp_Login, 0, sp_Login.Length); + } + catch (Exception) + { + // Not Important; + } + } + } + + break; + } + + break; + + + case "/MOTORSTORM2PS3_SVML/getEula": + { + switch (request.HttpMethod) + { + case "GET": + HttpListenerRequest req = request; + HttpListenerResponse resp = response; + resp.Headers.Set("Content-Type", "text/xml"); + + string clientMac = req.Headers.Get("X-SVOMac"); + string serverMac = SVOProcessor.CalcuateSVOMac(clientMac); + if (string.IsNullOrEmpty(serverMac)) + { + response.StatusCode = (int)HttpStatusCode.Forbidden; + return; + } + else + { + /* + if (!req.HasEntityBody) + { + response.StatusCode = (int)System.Net.HttpStatusCode.Forbidden; + return; + } + */ + resp.Headers.Set("X-SVOMac", serverMac); + + byte[] getEula = null; + + getEula = Encoding.UTF8.GetBytes(@" + + + Test + true + + "); + + resp.OutputStream.Write(getEula); +#if DEBUG + LoggerAccessor.LogInfo($"Start getEula for Resistance: Fall of Man SENT!"); +#endif + } + break; + } + break; + } + + case "/MOTORSTORM2PS3_SVML/getAnnouncement": + { + switch (request.HttpMethod) + { + case "GET": + HttpListenerRequest req = request; + HttpListenerResponse resp = response; + resp.Headers.Set("Content-Type", "text/xml"); + + string clientMac = req.Headers.Get("X-SVOMac"); + string serverMac = SVOProcessor.CalcuateSVOMac(clientMac); + if (string.IsNullOrEmpty(serverMac)) + { + response.StatusCode = (int)HttpStatusCode.Forbidden; + return; + } + else + { + /* + if (!req.HasEntityBody) + { + response.StatusCode = (int)System.Net.HttpStatusCode.Forbidden; + return; + } + */ + resp.Headers.Set("X-SVOMac", serverMac); + + byte[] getEula = null; + + getEula = Encoding.UTF8.GetBytes(@" + + + Test Announcement + + "); + + resp.OutputStream.Write(getEula); +#if DEBUG + LoggerAccessor.LogInfo($"Start getEula for Resistance: Fall of Man SENT!"); +#endif + } + break; + } + break; + } + + default: + response.StatusCode = (int)System.Net.HttpStatusCode.Forbidden; + break; + + #endregion + } + } + } + catch (Exception ex) + { + LoggerAccessor.LogError($"[SVO] - Starhawk_SVO thrown an assertion - {ex}"); + response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError; + } + } + } +} diff --git a/SpecializedServers/SVO/Games/PS3/SocomConfrontation.cs b/SpecializedServers/SVO/Games/PS3/SocomConfrontation.cs index c8ec3d1d1..9c42891ad 100644 --- a/SpecializedServers/SVO/Games/PS3/SocomConfrontation.cs +++ b/SpecializedServers/SVO/Games/PS3/SocomConfrontation.cs @@ -25,7 +25,7 @@ public static async Task SocomConfrontation_SVO(HttpListenerRequest request, Htt switch (request.Url.AbsolutePath) { #region SOCOMCONFRONTATION - case "/SOCOMCF_SVML/index.jsp": + case "/CONFRONTATION_XML/index.jsp": switch (request.HttpMethod) { @@ -58,7 +58,7 @@ public static async Task SocomConfrontation_SVO(HttpListenerRequest request, Htt languageID = 1; } - response.Headers.Set("Content-Type", "text/svml; charset=UTF-8"); + response.Headers.Set("Content-Type", "text/xml; charset=UTF-8"); response.Headers.Set("X-SVOMac", serverMac); response.Headers.Set("X-Powered-By", "MultiServer"); response.Headers.Set("Date", DateTime.Now.ToString("r")); @@ -66,7 +66,7 @@ public static async Task SocomConfrontation_SVO(HttpListenerRequest request, Htt byte[]? index = null; if (SVOServerConfiguration.SVOHTTPSBypass) - index = Encoding.UTF8.GetBytes(" \r\n\r\n " + + index = Encoding.UTF8.GetBytes(" \r\n\r\n " + $" \r\n " + "\r\n " + "\r\n\t" + @@ -121,9 +121,9 @@ public static async Task SocomConfrontation_SVO(HttpListenerRequest request, Htt "/>\r\n \r\n " + "\r\n " + "\r\n\r\n " + - "\r\n"); + "\r\n"); else - index = Encoding.UTF8.GetBytes(" \r\n\r\n " + + index = Encoding.UTF8.GetBytes(" \r\n\r\n " + $" \r\n " + "\r\n " + "\r\n\t" + @@ -178,7 +178,7 @@ public static async Task SocomConfrontation_SVO(HttpListenerRequest request, Htt "/>\r\n \r\n " + "\r\n " + "\r\n\r\n " + - "\r\n"); + "\r\n"); response.StatusCode = (int)System.Net.HttpStatusCode.OK; @@ -200,7 +200,7 @@ public static async Task SocomConfrontation_SVO(HttpListenerRequest request, Htt } break; - case "/SOCOMCF_SVML/account/SP_Login_Submit.jsp": + case "/CONFRONTATION_XML/account/SP_Login_Submit.jsp": switch (request.HttpMethod) { case "POST": @@ -338,7 +338,7 @@ await SVOServerConfiguration.Database.GetAccountByName(psnname, 21784).ContinueW break; - case "/SOCOMCF_SVML/home.jsp": + case "/CONFRONTATION_XML/home.jsp": switch (request.HttpMethod) { @@ -386,7 +386,7 @@ await SVOServerConfiguration.Database.GetAccountByName(psnname, 21784).ContinueW } break; - case "/SOCOMCF_SVML/account/Logout.jsp": + case "/CONFRONTATION_XML/account/Logout.jsp": switch (request.HttpMethod) { diff --git a/SpecializedServers/SVO/SVOServer.cs b/SpecializedServers/SVO/SVOServer.cs index 03340e245..858d5d006 100644 --- a/SpecializedServers/SVO/SVOServer.cs +++ b/SpecializedServers/SVO/SVOServer.cs @@ -274,13 +274,15 @@ private async Task ProcessContext(HttpListenerContext? ctx) await PlayStationHome.Home_SVO(ctx.Request, ctx.Response); else if (absolutepath.Contains("/WARHAWK_SVML/")) await Warhawk.Warhawk_SVO(ctx.Request, ctx.Response); + else if (absolutepath.Contains("/MOTORSTORM2PS3_SVML/") || absolutepath.Contains("/MOTORSTORM2PS3_XML/")) + await MotorstormPR2.MotorStormPR_SVO(ctx.Request, ctx.Response); else if (absolutepath.Contains("/motorstorm3ps3_xml/")) await MotorStormApocalypse.MSApocalypse_SVO(ctx.Request, ctx.Response); else if (absolutepath.Contains("/BUZZPS3_SVML/")) await BuzzQuizGame.BuzzQuizGame_SVO(ctx.Request, ctx.Response); else if (absolutepath.Contains("/BOURBON_XML/")) await Starhawk.Starhawk_SVO(ctx.Request, ctx.Response); - else if (absolutepath.Contains("/SOCOMCF_SVML/")) + else if (absolutepath.Contains("/CONFRONTATION_XML/")) await SocomConfrontation.SocomConfrontation_SVO(ctx.Request, ctx.Response); else if (absolutepath.Contains("/SINGSTARPS3_SVML/")) await SingStar.Singstar_SVO(ctx.Request, ctx.Response); @@ -289,7 +291,6 @@ private async Task ProcessContext(HttpListenerContext? ctx) else { // Only meant to be used with fairly small files. - string filePath = Path.Combine(SVOServerConfiguration.SVOStaticFolder, absolutepath[1..]); if (File.Exists(filePath)) diff --git a/WebServers/HTTPSecureServerLite/HttpsProcessor.cs b/WebServers/HTTPSecureServerLite/HttpsProcessor.cs index 685555204..b778a7f8d 100644 --- a/WebServers/HTTPSecureServerLite/HttpsProcessor.cs +++ b/WebServers/HTTPSecureServerLite/HttpsProcessor.cs @@ -2062,7 +2062,7 @@ private static async Task SendFile(HttpContextBase ctx, string encoding, s if (!string.IsNullOrEmpty(EtagMD5)) { ctx.Response.Headers.Add("ETag", EtagMD5); - ctx.Response.Headers.Add("expires", DateTime.Now.AddMinutes(30).ToString("r")); + ctx.Response.Headers.Add("Expires", DateTime.Now.AddMinutes(30).ToString("r")); } ctx.Response.StatusCode = 304; sent = await ctx.Response.Send(); @@ -2072,7 +2072,7 @@ private static async Task SendFile(HttpContextBase ctx, string encoding, s if (!string.IsNullOrEmpty(EtagMD5)) { ctx.Response.Headers.Add("ETag", EtagMD5); - ctx.Response.Headers.Add("expires", DateTime.Now.AddMinutes(30).ToString("r")); + ctx.Response.Headers.Add("Expires", DateTime.Now.AddMinutes(30).ToString("r")); } if (ctx.Response.ChunkedTransfer) diff --git a/WebServers/HTTPServer/HttpProcessor.cs b/WebServers/HTTPServer/HttpProcessor.cs index 5235467ed..d5382060b 100644 --- a/WebServers/HTTPServer/HttpProcessor.cs +++ b/WebServers/HTTPServer/HttpProcessor.cs @@ -1296,7 +1296,7 @@ private static void WriteResponse(Stream stream, HttpRequest request, HttpRespon if (!string.IsNullOrEmpty(EtagMD5)) { response.Headers.Add("ETag", EtagMD5); - response.Headers.Add("expires", DateTime.Now.AddMinutes(30).ToString("r")); + response.Headers.Add("Expires", DateTime.Now.AddMinutes(30).ToString("r")); } response.HttpStatusCode = HttpStatusCode.NotModified; @@ -1341,7 +1341,7 @@ private static void WriteResponse(Stream stream, HttpRequest request, HttpRespon if (!string.IsNullOrEmpty(EtagMD5)) { response.Headers.Add("ETag", EtagMD5); - response.Headers.Add("expires", DateTime.Now.AddMinutes(30).ToString("r")); + response.Headers.Add("Expires", DateTime.Now.AddMinutes(30).ToString("r")); } if (File.Exists(filePath)) response.Headers.Add("Last-Modified", File.GetLastWriteTime(filePath).ToString("r")); @@ -1894,7 +1894,7 @@ private static void Handle_LocalFile_Stream(Stream stream, HttpRequest request, if (!string.IsNullOrEmpty(EtagMD5)) { response.Headers.Add("ETag", EtagMD5); - response.Headers.Add("expires", DateTime.Now.AddMinutes(30).ToString("r")); + response.Headers.Add("Expires", DateTime.Now.AddMinutes(30).ToString("r")); } response.HttpStatusCode = HttpStatusCode.NotModified; @@ -1932,7 +1932,7 @@ private static void Handle_LocalFile_Stream(Stream stream, HttpRequest request, if (!string.IsNullOrEmpty(EtagMD5)) { response.Headers.Add("ETag", EtagMD5); - response.Headers.Add("expires", DateTime.Now.AddMinutes(30).ToString("r")); + response.Headers.Add("Expires", DateTime.Now.AddMinutes(30).ToString("r")); } if (File.Exists(filePath)) response.Headers.Add("Last-Modified", File.GetLastWriteTime(filePath).ToString("r")); From bdb032209914246d69af5e4c6e81d18bbbe8d4fd Mon Sep 17 00:00:00 2001 From: JumpSuit <26616362+Jump-Suit@users.noreply.github.com> Date: Tue, 10 Dec 2024 21:12:38 -0600 Subject: [PATCH 10/16] Added Class Name to Ubi BuildDB Logs --- .../BuildDBPullService/BuildDBPullServiceHandler.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/AuxiliaryServices/WebAPIService/UBISOFT/BuildAPI/BuildDBPullService/BuildDBPullServiceHandler.cs b/AuxiliaryServices/WebAPIService/UBISOFT/BuildAPI/BuildDBPullService/BuildDBPullServiceHandler.cs index af0cd8a9c..6b2be9162 100644 --- a/AuxiliaryServices/WebAPIService/UBISOFT/BuildAPI/BuildDBPullService/BuildDBPullServiceHandler.cs +++ b/AuxiliaryServices/WebAPIService/UBISOFT/BuildAPI/BuildDBPullService/BuildDBPullServiceHandler.cs @@ -40,7 +40,7 @@ public static string buildDBRequestParser(byte[] PostData, string ContentType) case "GetCurrentLauncherVersion": { - LoggerAccessor.LogInfo($"GetCurrentLauncherVersion: TRIGGERED!"); + LoggerAccessor.LogInfo($"[BuildDBPullService] - GetCurrentLauncherVersion: TRIGGERED!"); return @" Date: Tue, 10 Dec 2024 21:15:06 -0600 Subject: [PATCH 11/16] More Log Pre-pend fixes --- AuxiliaryServices/WebAPIService/CCPGames/Dust514Class.cs | 1 + .../WebAPIService/UBISOFT/BuildAPI/SoapBuildAPIClass.cs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/AuxiliaryServices/WebAPIService/CCPGames/Dust514Class.cs b/AuxiliaryServices/WebAPIService/CCPGames/Dust514Class.cs index f97496418..0b2d30b32 100644 --- a/AuxiliaryServices/WebAPIService/CCPGames/Dust514Class.cs +++ b/AuxiliaryServices/WebAPIService/CCPGames/Dust514Class.cs @@ -60,6 +60,7 @@ public string ProcessRequest(byte[] PostData, string ContentType, List Date: Thu, 12 Dec 2024 09:04:45 -0600 Subject: [PATCH 12/16] Adjust Dust514 check --- WebServers/HTTPServer/HttpProcessor.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/WebServers/HTTPServer/HttpProcessor.cs b/WebServers/HTTPServer/HttpProcessor.cs index c9cd9fde3..8ce4c1b6b 100644 --- a/WebServers/HTTPServer/HttpProcessor.cs +++ b/WebServers/HTTPServer/HttpProcessor.cs @@ -340,10 +340,12 @@ public void HandleClient(TcpClient? tcpClient, ushort ListenerPort) { default: + #region Dust 514 dcrest - //CCPGamesDomains.Contains(Host) || - if (Host.Contains("26004") //Check for Dust514 specific Port!! - && !string.IsNullOrEmpty(Method)) + if (request.ServerPort == 26004 //Check for Dust514 specific Port!! + && !string.IsNullOrEmpty(Method) + && request.Headers != null + && request.RetrieveHeaderValue("X-CCP-User-Agent", true).Contains("CCPGamesCrestClient") { LoggerAccessor.LogInfo($"[HTTP] - {clientip}:{clientport} Identified a Dust514 method : {absolutepath}"); From d03705c4a70563f16c1f96dd051e7b0c3a6a63cc Mon Sep 17 00:00:00 2001 From: JumpSuit <26616362+Jump-Suit@users.noreply.github.com> Date: Thu, 12 Dec 2024 09:04:58 -0600 Subject: [PATCH 13/16] Update HttpProcessor.cs --- WebServers/HTTPServer/HttpProcessor.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/WebServers/HTTPServer/HttpProcessor.cs b/WebServers/HTTPServer/HttpProcessor.cs index 8ce4c1b6b..1797e86e5 100644 --- a/WebServers/HTTPServer/HttpProcessor.cs +++ b/WebServers/HTTPServer/HttpProcessor.cs @@ -340,7 +340,6 @@ public void HandleClient(TcpClient? tcpClient, ushort ListenerPort) { default: - #region Dust 514 dcrest if (request.ServerPort == 26004 //Check for Dust514 specific Port!! && !string.IsNullOrEmpty(Method) From 9084f8966bbc978f7abf103a88d19e23b403762c Mon Sep 17 00:00:00 2001 From: JumpSuit <26616362+Jump-Suit@users.noreply.github.com> Date: Thu, 12 Dec 2024 09:29:12 -0600 Subject: [PATCH 14/16] Update HttpProcessor.cs --- WebServers/HTTPServer/HttpProcessor.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/WebServers/HTTPServer/HttpProcessor.cs b/WebServers/HTTPServer/HttpProcessor.cs index 1797e86e5..7dd156b50 100644 --- a/WebServers/HTTPServer/HttpProcessor.cs +++ b/WebServers/HTTPServer/HttpProcessor.cs @@ -343,7 +343,6 @@ public void HandleClient(TcpClient? tcpClient, ushort ListenerPort) #region Dust 514 dcrest if (request.ServerPort == 26004 //Check for Dust514 specific Port!! && !string.IsNullOrEmpty(Method) - && request.Headers != null && request.RetrieveHeaderValue("X-CCP-User-Agent", true).Contains("CCPGamesCrestClient") { LoggerAccessor.LogInfo($"[HTTP] - {clientip}:{clientport} Identified a Dust514 method : {absolutepath}"); From 5fb11cecd54e6ead3495032bd32df25e35d4cb06 Mon Sep 17 00:00:00 2001 From: JumpSuit <26616362+Jump-Suit@users.noreply.github.com> Date: Thu, 12 Dec 2024 12:45:51 -0600 Subject: [PATCH 15/16] compile error fix --- WebServers/HTTPServer/HttpProcessor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebServers/HTTPServer/HttpProcessor.cs b/WebServers/HTTPServer/HttpProcessor.cs index 7dd156b50..89dddcd87 100644 --- a/WebServers/HTTPServer/HttpProcessor.cs +++ b/WebServers/HTTPServer/HttpProcessor.cs @@ -343,7 +343,7 @@ public void HandleClient(TcpClient? tcpClient, ushort ListenerPort) #region Dust 514 dcrest if (request.ServerPort == 26004 //Check for Dust514 specific Port!! && !string.IsNullOrEmpty(Method) - && request.RetrieveHeaderValue("X-CCP-User-Agent", true).Contains("CCPGamesCrestClient") + && request.RetrieveHeaderValue("X-CCP-User-Agent", true).Contains("CCPGamesCrestClient")) { LoggerAccessor.LogInfo($"[HTTP] - {clientip}:{clientport} Identified a Dust514 method : {absolutepath}"); From 733f66dbfb97bbd4550b7871a134c99e4c9bc12f Mon Sep 17 00:00:00 2001 From: JumpSuit <26616362+Jump-Suit@users.noreply.github.com> Date: Fri, 13 Dec 2024 07:11:17 -0600 Subject: [PATCH 16/16] Adjust PS2Float from Main --- .../EmotionEngine.Emulator/PS2Float.cs | 309 ++++++++---------- 1 file changed, 137 insertions(+), 172 deletions(-) diff --git a/BackendServices/CastleLibrary/EmotionEngine.Emulator/PS2Float.cs b/BackendServices/CastleLibrary/EmotionEngine.Emulator/PS2Float.cs index 46cb4612c..a1b256bdc 100644 --- a/BackendServices/CastleLibrary/EmotionEngine.Emulator/PS2Float.cs +++ b/BackendServices/CastleLibrary/EmotionEngine.Emulator/PS2Float.cs @@ -3,12 +3,8 @@ namespace EmotionEngine.Emulator { // Adapted from: https://github.com/gregorygaines/ps2-floating-point-rs - public class Ps2Float : IComparable + public class PS2Float : IComparable { - public bool Sign { get; private set; } - public byte Exponent { get; private set; } - public uint Mantissa { get; private set; } - public const byte BIAS = 127; public const uint SIGNMASK = 0x80000000; public const uint MAX_FLOATING_POINT_VALUE = 0x7FFFFFFF; @@ -44,50 +40,46 @@ public class Ps2Float : IComparable 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 16, 16, 16, 16, 16, 16, 16, 16, 24, 24, 24, 24, 24, 24, 24 }; - public Ps2Float(uint value) - { - Sign = ((value >> 31) & 1) != 0; - Exponent = (byte)((value >> 23) & 0xFF); - Mantissa = value & 0x7FFFFF; - } + public uint Raw { get; private set; } - public Ps2Float(bool sign, byte exponent, uint mantissa) + public uint Mantissa => Raw & 0x7FFFFF; + public byte Exponent => (byte)((Raw >> 23) & 0xFF); + public bool Sign => ((Raw >> 31) & 1) != 0; + + public PS2Float(uint raw) { - Sign = sign; - Exponent = exponent; - Mantissa = mantissa; + Raw = raw; } - public static Ps2Float Max() + public PS2Float(bool sign, byte exponent, uint mantissa) { - return new Ps2Float(MAX_FLOATING_POINT_VALUE); + Raw = 0; + Raw |= (sign ? 1u : 0u) << 31; + Raw |= (uint)(exponent << 23); + Raw |= mantissa; } - public static Ps2Float Min() + public static PS2Float Max() { - return new Ps2Float(MIN_FLOATING_POINT_VALUE); + return new PS2Float(MAX_FLOATING_POINT_VALUE); } - public static Ps2Float One() + public static PS2Float Min() { - return new Ps2Float(ONE); + return new PS2Float(MIN_FLOATING_POINT_VALUE); } - public static Ps2Float MinOne() + public static PS2Float One() { - return new Ps2Float(MIN_ONE); + return new PS2Float(ONE); } - public uint AsUInt32() + public static PS2Float MinOne() { - uint result = 0; - result |= (Sign ? 1u : 0u) << 31; - result |= (uint)(Exponent << 23); - result |= Mantissa; - return result; + return new PS2Float(MIN_ONE); } - public Ps2Float Add(Ps2Float addend) + public PS2Float Add(PS2Float addend) { if (IsDenormalized() || addend.IsDenormalized()) return SolveAddSubDenormalizedOperation(this, addend, true); @@ -95,12 +87,11 @@ public Ps2Float Add(Ps2Float addend) if (IsAbnormal() && addend.IsAbnormal()) return SolveAbnormalAdditionOrSubtractionOperation(this, addend, true); - uint a = AsUInt32(); - uint b = addend.AsUInt32(); - int temp = 0; + uint a = Raw; + uint b = addend.Raw; // Exponent difference - int expDiff = ((int)(a >> 23) & 0xff) - ((int)(b >> 23) & 0xff); + int expDiff = ((int)(a >> 23) & 0xFF) - ((int)(b >> 23) & 0xFF); // diff = 25 .. 255 , expt < expd if (expDiff >= 25) @@ -111,8 +102,7 @@ public Ps2Float Add(Ps2Float addend) else if (expDiff > 0) { expDiff = expDiff - 1; - temp = unchecked((int)MIN_FLOATING_POINT_VALUE) << expDiff; - b = (uint)(temp & b); + b = (uint)((unchecked((int)MIN_FLOATING_POINT_VALUE) << expDiff) & b); } // diff = -255 .. -25, expd < expt else if (expDiff <= -25) @@ -124,14 +114,13 @@ public Ps2Float Add(Ps2Float addend) { expDiff = -expDiff; expDiff = expDiff - 1; - temp = unchecked((int)MIN_FLOATING_POINT_VALUE) << expDiff; - a = (uint)(a & temp); + a = (uint)(a & (unchecked((int)MIN_FLOATING_POINT_VALUE) << expDiff)); } - return new Ps2Float(a).DoAdd(new Ps2Float(b)); + return new PS2Float(a).DoAdd(new PS2Float(b)); } - public Ps2Float Sub(Ps2Float subtrahend) + public PS2Float Sub(PS2Float subtrahend) { if (IsDenormalized() || subtrahend.IsDenormalized()) return SolveAddSubDenormalizedOperation(this, subtrahend, false); @@ -139,12 +128,11 @@ public Ps2Float Sub(Ps2Float subtrahend) if (IsAbnormal() && subtrahend.IsAbnormal()) return SolveAbnormalAdditionOrSubtractionOperation(this, subtrahend, false); - uint a = AsUInt32(); - uint b = subtrahend.AsUInt32(); - int temp = 0; + uint a = Raw; + uint b = subtrahend.Raw; // Exponent difference - int expDiff = ((int)(a >> 23) & 0xff) - ((int)(b >> 23) & 0xff); + int expDiff = ((int)(a >> 23) & 0xFF) - ((int)(b >> 23) & 0xFF); // diff = 25 .. 255 , expt < expd if (expDiff >= 25) @@ -155,8 +143,7 @@ public Ps2Float Sub(Ps2Float subtrahend) else if (expDiff > 0) { expDiff = expDiff - 1; - temp = unchecked((int)MIN_FLOATING_POINT_VALUE) << expDiff; - b = (uint)(temp & b); + b = (uint)((unchecked((int)MIN_FLOATING_POINT_VALUE) << expDiff) & b); } // diff = -255 .. -25, expd < expt else if (expDiff <= -25) @@ -168,14 +155,13 @@ public Ps2Float Sub(Ps2Float subtrahend) { expDiff = -expDiff; expDiff = expDiff - 1; - temp = unchecked((int)MIN_FLOATING_POINT_VALUE) << expDiff; - a = (uint)(a & temp); + a = (uint)(a & (unchecked((int)MIN_FLOATING_POINT_VALUE) << expDiff)); } - return new Ps2Float(a).DoAdd(Neg(new Ps2Float(b))); + return new PS2Float(a).DoAdd(new PS2Float(b).Negate()); } - public Ps2Float Mul(Ps2Float mulend) + public PS2Float Mul(PS2Float mulend) { if (IsDenormalized() || mulend.IsDenormalized()) return SolveMultiplicationDenormalizedOperation(this, mulend); @@ -184,17 +170,12 @@ public Ps2Float Mul(Ps2Float mulend) return SolveAbnormalMultiplicationOrDivisionOperation(this, mulend, true); if (IsZero() || mulend.IsZero()) - { - return new Ps2Float(0) - { - Sign = DetermineMultiplicationDivisionOperationSign(this, mulend) - }; - } + return new PS2Float(DetermineMultiplicationDivisionOperationSign(this, mulend), 0, 0); return DoMul(mulend); } - public Ps2Float Div(Ps2Float divend) + public PS2Float Div(PS2Float divend) { if (IsDenormalized() || divend.IsDenormalized()) return SolveDivisionDenormalizedOperation(this, divend); @@ -203,19 +184,14 @@ public Ps2Float Div(Ps2Float divend) return SolveAbnormalMultiplicationOrDivisionOperation(this, divend, false); if (IsZero()) - { - return new Ps2Float(0) - { - Sign = DetermineMultiplicationDivisionOperationSign(this, divend) - }; - } + return new PS2Float(DetermineMultiplicationDivisionOperationSign(this, divend), 0, 0); else if (divend.IsZero()) return DetermineMultiplicationDivisionOperationSign(this, divend) ? Min() : Max(); return DoDiv(divend); } - private Ps2Float DoAdd(Ps2Float other) + private PS2Float DoAdd(PS2Float other) { const byte roundingMultiplier = 6; @@ -228,15 +204,15 @@ private Ps2Float DoAdd(Ps2Float other) return this; // http://graphics.stanford.edu/~seander/bithacks.html#ConditionalNegate - uint sign1 = (uint)((int)AsUInt32() >> 31); + uint sign1 = (uint)((int)Raw >> 31); int selfMantissa = (int)(((Mantissa | 0x800000) ^ sign1) - sign1); - uint sign2 = (uint)((int)other.AsUInt32() >> 31); + uint sign2 = (uint)((int)other.Raw >> 31); int otherMantissa = (int)(((other.Mantissa | 0x800000) ^ sign2) - sign2); int man = (selfMantissa << roundingMultiplier) + ((otherMantissa << roundingMultiplier) >> resExponent); int absMan = Math.Abs(man); if (absMan == 0) - return new Ps2Float(0); + return new PS2Float(0); int rawExp = selfExponent - roundingMultiplier; @@ -251,112 +227,111 @@ private Ps2Float DoAdd(Ps2Float other) if (rawExp > 255) return man < 0 ? Min() : Max(); else if (rawExp <= 0) - return new Ps2Float(man < 0, 0, 0); + return new PS2Float(man < 0, 0, 0); - return new Ps2Float((uint)man & SIGNMASK | (uint)rawExp << 23 | ((uint)absMan & 0x7FFFFF)).RoundTowardsZero(); + return new PS2Float((uint)man & SIGNMASK | (uint)rawExp << 23 | ((uint)absMan & 0x7FFFFF)); } - private Ps2Float DoMul(Ps2Float other) + private PS2Float DoMul(PS2Float other) { byte selfExponent = Exponent; byte otherExponent = other.Exponent; uint selfMantissa = Mantissa | 0x800000; uint otherMantissa = other.Mantissa | 0x800000; - uint sign = (AsUInt32() ^ other.AsUInt32()) & SIGNMASK; + uint sign = (Raw ^ other.Raw) & SIGNMASK; int resExponent = selfExponent + otherExponent - BIAS; uint resMantissa = (uint)(BoothMultiplier.MulMantissa(selfMantissa, otherMantissa) >> 23); - if (resMantissa > 0xffffff) + if (resMantissa > 0xFFFFFF) { resMantissa >>= 1; resExponent++; } if (resExponent > 255) - return new Ps2Float(sign | MAX_FLOATING_POINT_VALUE); + return new PS2Float(sign | MAX_FLOATING_POINT_VALUE); else if (resExponent <= 0) - return new Ps2Float(sign); + return new PS2Float(sign); - return new Ps2Float(sign | (uint)(resExponent << 23) | (resMantissa & 0x7fffff)).RoundTowardsZero(); + return new PS2Float(sign | (uint)(resExponent << 23) | (resMantissa & 0x7FFFFF)); } // Rounding can be slightly off: (PS2: 0x3F800000 / 0x3F800001 = 0x3F7FFFFF | SoftFloat/IEEE754: 0x3F800000 / 0x3F800001 = 0x3F7FFFFE). - private Ps2Float DoDiv(Ps2Float other) + private PS2Float DoDiv(PS2Float other) { - ulong selfMantissa64; + bool sign = DetermineMultiplicationDivisionOperationSign(this, other); uint selfMantissa = Mantissa | 0x800000; uint otherMantissa = other.Mantissa | 0x800000; int resExponent = Exponent - other.Exponent + BIAS; - - Ps2Float result = new Ps2Float(0) { Sign = DetermineMultiplicationDivisionOperationSign(this, other) }; + ulong selfMantissa64; if (resExponent > 255) - return result.Sign ? Min() : Max(); + return sign ? Min() : Max(); else if (resExponent <= 0) - return new Ps2Float(result.Sign, 0, 0); + return new PS2Float(sign, 0, 0); if (selfMantissa < otherMantissa) { --resExponent; if (resExponent == 0) - return new Ps2Float(result.Sign, 0, 0); + return new PS2Float(sign, 0, 0); selfMantissa64 = (ulong)selfMantissa << 31; } else selfMantissa64 = (ulong)selfMantissa << 30; uint resMantissa = (uint)(selfMantissa64 / otherMantissa); + if ((resMantissa & 0x3F) == 0) resMantissa |= ((ulong)otherMantissa * resMantissa != selfMantissa64) ? 1U : 0; - result.Exponent = (byte)resExponent; - result.Mantissa = (resMantissa + 0x39U /* Non-standard value, 40U in IEEE754 (PS2: rsqrt(0x40400000, 0x40400000) = 0x3FDDB3D7 -> IEEE754: rsqrt(0x40400000, 0x40400000) = 0x3FDDB3D8 */) >> 7; + resMantissa = (resMantissa + 0x40U) >> 7; - if (result.Mantissa > 0) + if (resMantissa > 0) { - int leadingBitPosition = GetMostSignificantBitPosition(result.Mantissa); + int leadingBitPosition = GetMostSignificantBitPosition(resMantissa); while (leadingBitPosition != IMPLICIT_LEADING_BIT_POS) { if (leadingBitPosition > IMPLICIT_LEADING_BIT_POS) { - result.Mantissa >>= 1; + resMantissa >>= 1; - int increasedExponent = result.Exponent + 1; + int increasedExponent = resExponent + 1; if (increasedExponent > 255) - return result.Sign ? Min() : Max(); + return sign ? Min() : Max(); - result.Exponent = (byte)increasedExponent; + resExponent = increasedExponent; leadingBitPosition--; } else if (leadingBitPosition < IMPLICIT_LEADING_BIT_POS) { - result.Mantissa <<= 1; + resMantissa <<= 1; - int decreasedExponent = result.Exponent - 1; + int decreasedExponent = resExponent - 1; if (decreasedExponent <= 0) - return new Ps2Float(result.Sign, 0, 0); + return new PS2Float(sign, 0, 0); - result.Exponent = (byte)decreasedExponent; + resExponent = decreasedExponent; leadingBitPosition++; } } } - result.Mantissa &= 0x7FFFFF; - return result.RoundTowardsZero(); + resMantissa &= 0x7FFFFF; + return new PS2Float(sign, (byte)resExponent, resMantissa).RoundTowardsZero(); } // Rounding can be slightly off: (PS2: rsqrt(0x7FFFFFF0) -> 0x5FB504ED | SoftFloat/IEEE754 rsqrt(0x7FFFFFF0) -> 0x5FB504EE). /// /// Returns the square root of x /// - public Ps2Float Sqrt() + public PS2Float Sqrt() { int t; int s = 0; @@ -364,15 +339,15 @@ public Ps2Float Sqrt() uint r = 0x01000000; /* r = moving bit from right to left */ if (IsDenormalized()) - return new Ps2Float(0); + return new PS2Float(0); // PS2 only takes positive numbers for SQRT, and convert if necessary. - int ix = (int)new Ps2Float(false, Exponent, Mantissa).AsUInt32(); + int ix = (int)new PS2Float(false, Exponent, Mantissa).Raw; /* extract mantissa and unbias exponent */ int m = (ix >> 23) - BIAS; - ix = (ix & 0x007fffff) | 0x00800000; + ix = (ix & 0x007FFFFF) | 0x00800000; if ((m & 1) == 1) { /* odd m, double x to make it even */ @@ -404,13 +379,13 @@ public Ps2Float Sqrt() q += q & 1; } - ix = (q >> 1) + 0x3f000000; + ix = (q >> 1) + 0x3F000000; ix += m << 23; - return new Ps2Float((uint)ix); + return new PS2Float((uint)ix); } - public Ps2Float Rsqrt(Ps2Float other) + public PS2Float Rsqrt(PS2Float other) { return Div(other.Sqrt()); } @@ -422,105 +397,110 @@ public bool IsDenormalized() public bool IsAbnormal() { - uint val = AsUInt32(); + uint val = Raw; return val == MAX_FLOATING_POINT_VALUE || val == MIN_FLOATING_POINT_VALUE || val == POSITIVE_INFINITY_VALUE || val == NEGATIVE_INFINITY_VALUE; } public bool IsZero() { - return (Abs()) == 0; + return Abs() == 0; } - public Ps2Float RoundTowardsZero() + public PS2Float RoundTowardsZero() { - return new Ps2Float((uint)Math.Truncate((double)AsUInt32())); + return new PS2Float((uint)Math.Truncate((double)Raw)); } - public int CompareTo(Ps2Float other) + public int CompareTo(PS2Float other) { - int selfTwoComplementVal = (int)(Abs()); + int selfTwoComplementVal = (int)Abs(); if (Sign) selfTwoComplementVal = -selfTwoComplementVal; - int otherTwoComplementVal = (int)(other.Abs()); + int otherTwoComplementVal = (int)other.Abs(); if (other.Sign) otherTwoComplementVal = -otherTwoComplementVal; return selfTwoComplementVal.CompareTo(otherTwoComplementVal); } - public int CompareOperand(Ps2Float other) + public int CompareOperand(PS2Float other) { - int selfTwoComplementVal = (int)(Abs()); - int otherTwoComplementVal = (int)(other.Abs()); + int selfTwoComplementVal = (int)Abs(); + int otherTwoComplementVal = (int)other.Abs(); return selfTwoComplementVal.CompareTo(otherTwoComplementVal); } public uint Abs() { - return AsUInt32() & MAX_FLOATING_POINT_VALUE; + return Raw & MAX_FLOATING_POINT_VALUE; + } + + private PS2Float Negate() + { + return new PS2Float(Raw ^ SIGNMASK); } - private static Ps2Float SolveAbnormalAdditionOrSubtractionOperation(Ps2Float a, Ps2Float b, bool add) + private static PS2Float SolveAbnormalAdditionOrSubtractionOperation(PS2Float a, PS2Float b, bool add) { - uint aval = a.AsUInt32(); - uint bval = b.AsUInt32(); + uint aval = a.Raw; + uint bval = b.Raw; if (aval == MAX_FLOATING_POINT_VALUE && bval == MAX_FLOATING_POINT_VALUE) - return add ? Max() : new Ps2Float(0); + return add ? Max() : new PS2Float(0); if (aval == MIN_FLOATING_POINT_VALUE && bval == MIN_FLOATING_POINT_VALUE) - return add ? Min() : new Ps2Float(0); + return add ? Min() : new PS2Float(0); if (aval == MIN_FLOATING_POINT_VALUE && bval == MAX_FLOATING_POINT_VALUE) - return add ? new Ps2Float(0) : Min(); + return add ? new PS2Float(0) : Min(); if (aval == MAX_FLOATING_POINT_VALUE && bval == MIN_FLOATING_POINT_VALUE) - return add ? new Ps2Float(0) : Max(); + return add ? new PS2Float(0) : Max(); if (aval == POSITIVE_INFINITY_VALUE && bval == POSITIVE_INFINITY_VALUE) - return add ? Max() : new Ps2Float(0); + return add ? Max() : new PS2Float(0); if (aval == NEGATIVE_INFINITY_VALUE && bval == POSITIVE_INFINITY_VALUE) - return add ? new Ps2Float(0) : Min(); + return add ? new PS2Float(0) : Min(); if (aval == POSITIVE_INFINITY_VALUE && bval == NEGATIVE_INFINITY_VALUE) - return add ? new Ps2Float(0) : Max(); + return add ? new PS2Float(0) : Max(); if (aval == NEGATIVE_INFINITY_VALUE && bval == NEGATIVE_INFINITY_VALUE) - return add ? Min() : new Ps2Float(0); + return add ? Min() : new PS2Float(0); if (aval == MAX_FLOATING_POINT_VALUE && bval == POSITIVE_INFINITY_VALUE) - return add ? Max() : new Ps2Float(0x7F7FFFFE); + return add ? Max() : new PS2Float(0x7F7FFFFE); if (aval == MAX_FLOATING_POINT_VALUE && bval == NEGATIVE_INFINITY_VALUE) - return add ? new Ps2Float(0x7F7FFFFE) : Max(); + return add ? new PS2Float(0x7F7FFFFE) : Max(); if (aval == MIN_FLOATING_POINT_VALUE && bval == POSITIVE_INFINITY_VALUE) - return add ? new Ps2Float(0xFF7FFFFE) : Min(); + return add ? new PS2Float(0xFF7FFFFE) : Min(); if (aval == MIN_FLOATING_POINT_VALUE && bval == NEGATIVE_INFINITY_VALUE) - return add ? Min() : new Ps2Float(0xFF7FFFFE); + return add ? Min() : new PS2Float(0xFF7FFFFE); if (aval == POSITIVE_INFINITY_VALUE && bval == MAX_FLOATING_POINT_VALUE) - return add ? Max() : new Ps2Float(0xFF7FFFFE); + return add ? Max() : new PS2Float(0xFF7FFFFE); if (aval == POSITIVE_INFINITY_VALUE && bval == MIN_FLOATING_POINT_VALUE) - return add ? new Ps2Float(0xFF7FFFFE) : Max(); + return add ? new PS2Float(0xFF7FFFFE) : Max(); if (aval == NEGATIVE_INFINITY_VALUE && bval == MAX_FLOATING_POINT_VALUE) - return add ? new Ps2Float(0x7F7FFFFE) : Min(); + return add ? new PS2Float(0x7F7FFFFE) : Min(); if (aval == NEGATIVE_INFINITY_VALUE && bval == MIN_FLOATING_POINT_VALUE) - return add ? Min() : new Ps2Float(0x7F7FFFFE); + return add ? Min() : new PS2Float(0x7F7FFFFE); throw new InvalidOperationException("Unhandled abnormal add/sub floating point operation"); } - private static Ps2Float SolveAbnormalMultiplicationOrDivisionOperation(Ps2Float a, Ps2Float b, bool mul) + private static PS2Float SolveAbnormalMultiplicationOrDivisionOperation(PS2Float a, PS2Float b, bool mul) { - uint aval = a.AsUInt32(); - uint bval = b.AsUInt32(); + uint aval = a.Raw; + uint bval = b.Raw; if (mul) { @@ -591,87 +571,72 @@ private static Ps2Float SolveAbnormalMultiplicationOrDivisionOperation(Ps2Float return One(); if (aval == MAX_FLOATING_POINT_VALUE && bval == POSITIVE_INFINITY_VALUE) - return new Ps2Float(0x3FFFFFFF); + return new PS2Float(0x3FFFFFFF); if (aval == MAX_FLOATING_POINT_VALUE && bval == NEGATIVE_INFINITY_VALUE) - return new Ps2Float(0xBFFFFFFF); + return new PS2Float(0xBFFFFFFF); if (aval == MIN_FLOATING_POINT_VALUE && bval == POSITIVE_INFINITY_VALUE) - return new Ps2Float(0xBFFFFFFF); + return new PS2Float(0xBFFFFFFF); if (aval == MIN_FLOATING_POINT_VALUE && bval == NEGATIVE_INFINITY_VALUE) - return new Ps2Float(0x3FFFFFFF); + return new PS2Float(0x3FFFFFFF); if (aval == POSITIVE_INFINITY_VALUE && bval == MAX_FLOATING_POINT_VALUE) - return new Ps2Float(0x3F000001); + return new PS2Float(0x3F000001); if (aval == POSITIVE_INFINITY_VALUE && bval == MIN_FLOATING_POINT_VALUE) - return new Ps2Float(0xBF000001); + return new PS2Float(0xBF000001); if (aval == NEGATIVE_INFINITY_VALUE && bval == MAX_FLOATING_POINT_VALUE) - return new Ps2Float(0xBF000001); + return new PS2Float(0xBF000001); if (aval == NEGATIVE_INFINITY_VALUE && bval == MIN_FLOATING_POINT_VALUE) - return new Ps2Float(0x3F000001); + return new PS2Float(0x3F000001); } throw new InvalidOperationException("Unhandled abnormal mul/div floating point operation"); } - private static Ps2Float Neg(Ps2Float self) + private static PS2Float SolveAddSubDenormalizedOperation(PS2Float a, PS2Float b, bool add) { - return new Ps2Float(self.AsUInt32() ^ SIGNMASK); - } - - private static Ps2Float SolveAddSubDenormalizedOperation(Ps2Float a, Ps2Float b, bool add) - { - Ps2Float result; + bool sign = add ? DetermineAdditionOperationSign(a, b) : DetermineSubtractionOperationSign(a, b); if (a.IsDenormalized() && !b.IsDenormalized()) - result = b; + return new PS2Float(sign, b.Exponent, b.Mantissa); else if (!a.IsDenormalized() && b.IsDenormalized()) - result = a; + return new PS2Float(sign, a.Exponent, a.Mantissa); else if (a.IsDenormalized() && b.IsDenormalized()) - result = new Ps2Float(0); + return new PS2Float(sign, 0, 0); else throw new InvalidOperationException("Both numbers are not denormalized"); - - result.Sign = add ? DetermineAdditionOperationSign(a, b) : DetermineSubtractionOperationSign(a, b); - return result; } - private static Ps2Float SolveMultiplicationDenormalizedOperation(Ps2Float a, Ps2Float b) + private static PS2Float SolveMultiplicationDenormalizedOperation(PS2Float a, PS2Float b) { - return new Ps2Float(0) - { - Sign = DetermineMultiplicationDivisionOperationSign(a, b) - }; + return new PS2Float(DetermineMultiplicationDivisionOperationSign(a, b), 0, 0); } - private static Ps2Float SolveDivisionDenormalizedOperation(Ps2Float a, Ps2Float b) + private static PS2Float SolveDivisionDenormalizedOperation(PS2Float a, PS2Float b) { bool sign = DetermineMultiplicationDivisionOperationSign(a, b); - Ps2Float result; if (a.IsDenormalized() && !b.IsDenormalized()) - result = new Ps2Float(0); + return new PS2Float(sign, 0, 0); else if (!a.IsDenormalized() && b.IsDenormalized()) return sign ? Min() : Max(); else if (a.IsDenormalized() && b.IsDenormalized()) return sign ? Min() : Max(); else throw new InvalidOperationException("Both numbers are not denormalized"); - - result.Sign = sign; - return result; } - private static bool DetermineMultiplicationDivisionOperationSign(Ps2Float a, Ps2Float b) + private static bool DetermineMultiplicationDivisionOperationSign(PS2Float a, PS2Float b) { return a.Sign ^ b.Sign; } - private static bool DetermineAdditionOperationSign(Ps2Float a, Ps2Float b) + private static bool DetermineAdditionOperationSign(PS2Float a, PS2Float b) { if (a.IsZero() && b.IsZero()) { @@ -686,7 +651,7 @@ private static bool DetermineAdditionOperationSign(Ps2Float a, Ps2Float b) return a.CompareOperand(b) >= 0 ? a.Sign : b.Sign; } - private static bool DetermineSubtractionOperationSign(Ps2Float a, Ps2Float b) + private static bool DetermineSubtractionOperationSign(PS2Float a, PS2Float b) { if (a.IsZero() && b.IsZero()) { @@ -743,7 +708,7 @@ public override string ToString() { double res = ToDouble(); - uint value = AsUInt32(); + uint value = Raw; if (IsDenormalized()) return $"Denormalized({res:F6})"; else if (value == MAX_FLOATING_POINT_VALUE)