Jump to content
3DXChat Community

AlexRyder

Members
  • Posts

    247
  • Joined

  • Last visited

Reputation Activity

  1. Like
    AlexRyder got a reaction from Mar Mohan in World chat: 60 s delay killed the chat   
    Aaand the 60-second check is of course client-sided. Which means — workaroundable. Only took about 10 min to find it in the binaries
  2. Haha
    AlexRyder got a reaction from chloe in World chat: 60 s delay killed the chat   
    Aaand the 60-second check is of course client-sided. Which means — workaroundable. Only took about 10 min to find it in the binaries
  3. Haha
    AlexRyder got a reaction from ObsessiveStatistician in World chat: 60 s delay killed the chat   
    Aaand the 60-second check is of course client-sided. Which means — workaroundable. Only took about 10 min to find it in the binaries
  4. Haha
    AlexRyder got a reaction from Feuermond in World chat: 60 s delay killed the chat   
    Aaand the 60-second check is of course client-sided. Which means — workaroundable. Only took about 10 min to find it in the binaries
  5. Haha
    AlexRyder got a reaction from Aliviax in World chat: 60 s delay killed the chat   
    Aaand the 60-second check is of course client-sided. Which means — workaroundable. Only took about 10 min to find it in the binaries
  6. Like
    AlexRyder got a reaction from ☙𝔼𝕩❧ in World chat: 60 s delay killed the chat   
    Aaand the 60-second check is of course client-sided. Which means — workaroundable. Only took about 10 min to find it in the binaries
  7. Like
    AlexRyder got a reaction from Rob. in Features from mods in the official client   
    Just as an info note, it's still fairly simple to patch the compiled binaries to workaround certain security checks.
    For example, only took me a few minutes with IDA to find the player ignored check before processing chat messages:
     

     
    Can be easily patched as well. It only became impossible to add complicated stuff to the game, i.e. the good stuff.
     
    To make the game actually secure such checks should be performed server-side, not on the client.
  8. Like
    AlexRyder got a reaction from Halderim in Features from mods in the official client   
    Just as an info note, it's still fairly simple to patch the compiled binaries to workaround certain security checks.
    For example, only took me a few minutes with IDA to find the player ignored check before processing chat messages:
     

     
    Can be easily patched as well. It only became impossible to add complicated stuff to the game, i.e. the good stuff.
     
    To make the game actually secure such checks should be performed server-side, not on the client.
  9. Like
    AlexRyder got a reaction from ToxicallySweet in Features from mods in the official client   
    Just as an info note, it's still fairly simple to patch the compiled binaries to workaround certain security checks.
    For example, only took me a few minutes with IDA to find the player ignored check before processing chat messages:
     

     
    Can be easily patched as well. It only became impossible to add complicated stuff to the game, i.e. the good stuff.
     
    To make the game actually secure such checks should be performed server-side, not on the client.
  10. Like
    AlexRyder got a reaction from EvaSis in Features from mods in the official client   
    It could also have the HSV and alpha sliders though 
     

  11. Like
    AlexRyder got a reaction from Aliviax in Features from mods in the official client   
    It could also have the HSV and alpha sliders though 
     

  12. Like
    AlexRyder got a reaction from presciouss in Features from mods in the official client   
    It could also have the HSV and alpha sliders though 
     

  13. Like
    AlexRyder got a reaction from Niblette in Features from mods in the official client   
    It could also have the HSV and alpha sliders though 
     

  14. Like
    AlexRyder got a reaction from Anaganda in Features from mods in the official client   
    It could also have the HSV and alpha sliders though 
     

  15. Like
    AlexRyder got a reaction from Mar Mohan in Upcoming Updates Discussion   
    3dx places clothes models on top of the full avi models and uses alpha masks to hide parts of the body covered with clothes so that it won't randomly peek through.
    Adding texture layers to the models (i.e. tattoos and stuff) is fairly easy but requires modifying shaders. Stockings are implemented this way.
    Placing textures on random places of the models would be more complicated, but doable.
    Making earrings, piercings, gloves, etc.is for the most part a matter of modeling and rigging.
  16. Like
    AlexRyder got a reaction from Aliviax in Upcoming Updates Discussion   
    3dx places clothes models on top of the full avi models and uses alpha masks to hide parts of the body covered with clothes so that it won't randomly peek through.
    Adding texture layers to the models (i.e. tattoos and stuff) is fairly easy but requires modifying shaders. Stockings are implemented this way.
    Placing textures on random places of the models would be more complicated, but doable.
    Making earrings, piercings, gloves, etc.is for the most part a matter of modeling and rigging.
  17. Like
    AlexRyder got a reaction from THX in Upcoming Updates Discussion   
    3dx places clothes models on top of the full avi models and uses alpha masks to hide parts of the body covered with clothes so that it won't randomly peek through.
    Adding texture layers to the models (i.e. tattoos and stuff) is fairly easy but requires modifying shaders. Stockings are implemented this way.
    Placing textures on random places of the models would be more complicated, but doable.
    Making earrings, piercings, gloves, etc.is for the most part a matter of modeling and rigging.
  18. Like
    AlexRyder got a reaction from Aliviax in Letter to Gizmo about Unity 5   
    3dxChat is still using Unity 5.5 (pretty outdated version by now, from 2016), this blog post is about Unity 2017.
    And seriously, Windows XP in 2019?
  19. Like
    AlexRyder got a reaction from Kaysuh in Is there a simple way to stop the patcher?   
    The simplest and most obvious one — just rename Patcher.exe to something else, the game won't be able to run it then.
  20. Like
    AlexRyder got a reaction from MissD in Is there a simple way to stop the patcher?   
    The simplest and most obvious one — just rename Patcher.exe to something else, the game won't be able to run it then.
  21. Like
    AlexRyder got a reaction from Gizmo in Bug Tracker (3DXChat 2.6)   
    The check for gift id < 787348 seems to be rather unreliable. The ids may be mixed in the database, or new entries may be inserted in place of earlier removed ones, dunno, that depends on the server backend.
    Weirdly enough, the date check can also misfire for some reason, so I would say the most reliable way is to do a validity check against the 1252 codepage before trying to convert data.
  22. Like
    AlexRyder got a reaction from Alliehotass in Bug Tracker (3DXChat 2.6)   
    But... it's not really a fix, the data in the database still stays broken. You should at least run this fixer on the database (though it's probably the worst way to deal with this problem ever). Also, the code in 383 is missing the check for broken encoding for profiles (some people have managed to change their data between 380 and 382) and a few special cases handling, which will probably still crash the profiles script.
    Also, a lot of gifs are missing from people's profiles and the gift count received with the profile in most cases is now greater than the actual gift count. It seems like the gifts from deleted accounts have not been transferred from the old database, which is obviously an error.
  23. Like
    AlexRyder got a reaction from Luvs in Bug Tracker (3DXChat 2.6)   
    But... it's not really a fix, the data in the database still stays broken. You should at least run this fixer on the database (though it's probably the worst way to deal with this problem ever). Also, the code in 383 is missing the check for broken encoding for profiles (some people have managed to change their data between 380 and 382) and a few special cases handling, which will probably still crash the profiles script.
    Also, a lot of gifs are missing from people's profiles and the gift count received with the profile in most cases is now greater than the actual gift count. It seems like the gifts from deleted accounts have not been transferred from the old database, which is obviously an error.
  24. Like
    AlexRyder got a reaction from Mar Mohan in Bug Tracker (3DXChat 2.6)   
    Regarding the Bob and Betty issue: you currently have their data switched in the database (i.e. Betty should have id 1 and Bob — id 2). Since they are reverse the client tries to apply female char data to a male and vice versa.
     
    Edit:
    Correction. Betty now seems to occupy ids 2 and 3, Bob — ids 1 and 4, where ids 1 and 2 have working char data and broken profiles, and ids 3 and 4 have broken char data but working profiles. It's a mess.
  25. Like
    AlexRyder got a reaction from Mar Mohan in Bug Tracker (3DXChat 2.6)   
    A few corrections to the previous bugfix post. Apparently, the mess with the data in the database has gotten even more complicated since there are now old broken profiles with broken encodings, old broken profiles with normal encodings, and new profiles. Also, the gifts sent after the update has been rolled out don't need to be fixed.
     
    For the profiles:
    private void LoadProfile(string profileData) { profileData = profileData.Trim(); if (profileData.StartsWith("{", StringComparison.Ordinal)) { // New JSON profiles LoadJsonProfile(profileData); } else if (profileData.StartsWith("<profile>", StringComparison.Ordinal)) { // Old XML profiles LoadXmlProfile(profileData); } else { // Some very ancient string-concatenated profiles LoadLegacyProfile(profileData); } } // New JSON profiles private void LoadJsonProfile(string jsonData) { // Go on with deserialization here } // Old XML profiles private void LoadXmlProfile(string xmlData) { xmlData = FixBrokenUtf8Encoding(xmlData); // Since most of the xmls are now malformed, need to rebuild them manually StringBuilder sb = new StringBuilder(); sb.Append("<profile>"); AppendXmlTag(sb, xmlData, "age", "18", false, true); AppendXmlTag(sb, xmlData, "interest", "?", false, true); AppendXmlTag(sb, xmlData, "location", "3DXChat", false, true); AppendXmlTag(sb, xmlData, "about", "I love 3DXChat!", true, true); sb.Append("</profile>"); xmlData = sb.ToString(); // Remove illegal XML chars xmlData = SanitizeInvalidXmlCharacterReferences(xmlData); // Go on with deserialization here } // Sorta-fix for an UTF-8 --> Latin1 --> UTF-8 conversion private string FixBrokenUtf8Encoding(string text) { if (IsValidForEncoding(text, 1252)) { Encoding utf8 = Encoding.UTF8; Encoding latin1 = Encoding.GetEncoding(1252); byte[] bytes = Encoding.Convert(utf8, latin1, utf8.GetBytes(text)); return utf8.GetString(bytes); } return text; } // Sorta-check to figure out if we really need to fix the encoding, may misfire private bool IsValidForEncoding(string text, int codePage) { Encoding encoder = Encoding.GetEncoding(codePage, new EncoderExceptionFallback(), new DecoderExceptionFallback()); try { encoder.GetBytes(text); } catch (EncoderFallbackException) { return false; } return true; } private void AppendXmlTag(StringBuilder sb, string xmlData, string tag, string defaultValue, bool findMostInnerMatch, bool reparse) { string openTag = $"<{tag}>"; string closeTag = $"</{tag}>"; int startIndex; int endIndex; bool isMatch = false; if (findMostInnerMatch) { // Some profiles saved with client versions 380 and 381 are weirdly malformed and contain nested data, so, need to try and untangle that startIndex = xmlData.IndexOf(openTag, StringComparison.Ordinal) + openTag.Length; endIndex = startIndex >= openTag.Length && startIndex < xmlData.Length ? xmlData.LastIndexOf(closeTag, xmlData.Length - 1, xmlData.Length - startIndex, StringComparison.Ordinal) : -1; while (endIndex > -1) { isMatch = true; xmlData = xmlData.Substring(startIndex, endIndex - startIndex); startIndex = xmlData.IndexOf(openTag, StringComparison.Ordinal) + openTag.Length; endIndex = startIndex >= openTag.Length && startIndex < xmlData.Length ? xmlData.LastIndexOf(closeTag, xmlData.Length - 1, xmlData.Length - startIndex, StringComparison.Ordinal) : -1; } } else { startIndex = xmlData.IndexOf(openTag, StringComparison.Ordinal) + openTag.Length; endIndex = startIndex >= openTag.Length && startIndex < xmlData.Length ? xmlData.IndexOf(closeTag, startIndex, StringComparison.Ordinal) : -1; if (endIndex > -1) { isMatch = true; xmlData = xmlData.Substring(startIndex, endIndex - startIndex); } } if (isMatch) { if (reparse) { // Inner values can be a total mess now, so it's easier to just re-encode them xmlData = HttpUtility.HtmlEncode(HttpUtility.HtmlDecode(xmlData)); } sb.Append(openTag); sb.Append(xmlData); sb.Append(closeTag); } else { sb.Append(openTag); sb.Append(defaultValue); sb.Append(closeTag); } } private static Regex _xmlEncodedCharacterRegex = new Regex("(x?)([A-Fa-f0-9]+);"); private string SanitizeInvalidXmlCharacterReferences(string xmlData) { if (xmlData.IndexOf("", StringComparison.Ordinal) < 0) { return xmlData; } return _xmlEncodedCharacterRegex.Replace( xmlData, match => { string matchValue = match.Value; uint result; bool isParsed = matchValue[2] == 'x' ? uint.TryParse(matchValue.Substring(3, matchValue.Length - 4), NumberStyles.AllowHexSpecifier, NumberFormatInfo.InvariantInfo, out result) : uint.TryParse(matchValue.Substring(2, matchValue.Length - 3), NumberStyles.Integer, NumberFormatInfo.InvariantInfo, out result); return isParsed && !IsValidXmlChar((char)result) ? "�" : matchValue; }); } private bool IsValidXmlChar(char character) { return character == 0x9 || character == 0xa || character == 0xd || character >= 0x20 && character <= 0xd7ff || character >= 0xe000 && character <= 0xfffd || character >= 0x10000 && character <= 0x10ffff; } // Some very ancient string-concatenated profiles private void LoadLegacyProfile(string profileData) { string[] args = profileData.Split('|'); if (args.Length < 1) { return; } if (args.Length >= 5) { // Go on with deserialization here } } For the gifts:
    // The time the database was converted private static DateTime _patch380ReleaseDate = new DateTime(2018, 11, 15, 19, 0, 0, 0, DateTimeKind.Utc); private string FixBrokenGiftText(string giftText) { // Check if really need to fix the text if (giftText != null && timeStamp.ToUniversalTime() < _patch380ReleaseDate) { // Correct broken encoding Encoding utf8 = Encoding.UTF8; Encoding latin1 = Encoding.GetEncoding(1252); byte[] bytes = Encoding.Convert(utf8, latin1, utf8.GetBytes(giftText)); giftText = utf8.GetString(bytes); // Fix some string conversion leftovers giftText = giftText.Replace("\\'", "\'"); } return giftText; }
×
×
  • Create New...