NachoCheese

Newbie
Dec 10, 2017
95
136
Back in the day I used .
I still do.

Actually, it would be useful to get one or two active client ID's, maybe via private message, and keeping in mind that it could alter the saved games (there isn't much to play, though, so...). I've already tried some values, and for the time being I would keep "6" as value, it has given me the full patreon access screen:
I'd be careful about using those. If I were as paranoid about piracy as DS apparently is, I'd have something in place to automatically blacklist Patreons whos' IDs appear to be logged in from two or more places at once.

It turns out I don't have the time this week for a full protocol document, so I'll just throw something together on here in a follow-up post.
 
  • Like
Reactions: Hlextor

NachoCheese

Newbie
Dec 10, 2017
95
136
Rough Protocol Documentation: Glamour v0.5.

Note: These notes are based on a client that had already been bootstrapped, and with no Patreon account. Subsequent runs were intended to determine differences between authenticated and non-authenticated operation, but it doesn't look like much will change.

Client communicates with API endpoint at http:// sandlustgames.com /

Upon startup, client issues a GET request for /resources/game-data
API responds with a JSON object representing key-value pairs of filenames and what appear to be MD5 hashes of those filenames:

Code:
{
  "scripts.dll": "27b58bc01180293c88f72855c96616e8",
  "content": "b2e176d524e644cf511b415468b2df35",
  "scenes": "84dd8df8994c2b44c935b149ea76dd5a"
}
Client issues a GET request for /resources
API responds with a JSON object representing key-value pairs of filenames and what appear to be file sizes (number of bytes) of each file:

Code:
{
...
  "wardrobe/casual-3-big":1220652,
  "wardrobe/casual-3":22633,
  "wardrobe/evening-1-big":1019972,
  "wardrobe/evening-1":13460,
  "wardrobe/evening-2-big":1052070,
...
}
For missing (or presumably the wrong size) files, the client issues a GET request for the resource (ie: GET /images/backgrounds/cafe-hall)
The API responds with the resource (interestingly enough, still passed from Express, and not as a static resource from nginx)

After all resources have been loaded, client issues a POST request for /api/status with the following keys:
  • id: a UUID. I'm assuming this is used to look up the user's information through the Patreon API.
The API responds with a JSON object with the following keys:
  • patron: 0 (Assuming boolean: if this user is a Patron or not)
  • pledge: 0 (Assuming pledge value)
  • version: 5 (Assuming minor version of the client)
The client issues a POST request for /api/login with the following keys:
  • id: a UUID, same as the one previously seen.
  • lang: en the language mode in which the client should operate.
The API responds with a JSON object with the following keys:
  • status: ok
  • token: (a 164 byte string that appears to have several Base64 encoded segments separated by the '.' character)
    • Segment 1: a 36 byte Base64 encoded JSON object with the following keys:
      • alg: HS256
      • typ: JWT
      • Note:
    • Segment 2: an 83 byte Base64 encoded JSON object with the following keys:
      • id: The previously seen UUID
      • iat: The number of seconds since the UNIX epoch.
    • Segment 3: a 43 byte string that appears to be random data. (this base64 decodes to 32 bytes, so this is quite likely)
  • saves: an array (empty)
  • patron: false (if the user is a patron or not)
  • pledge: 0 (the pledge level of the patron)
The client issues a POST request for /api/start with the following keys:
  • token: the previously seen token
The API responds with a JSON object with the following keys:
  • state: event
  • simpleText: A JSON object with the following keys:
    • x: 890 (x offset in pixels)
    • y: 267 (y offset in pixels)
    • width: 700 (width value in pixels)
    • color: #f8dcab (HTML color code)
    • text: <size=34><color=#ffffff>Hi!</color></size>\nMy name is Kate, what's yours? Wait, don't tell me. I'm not supposed to know about you... (Literal HTML)
  • sprites: Array containing one or more JSON objects with asset names and x,y offsets
  • buttons: Array containing one or more JSON objects with asset names and x,y offsets
  • leftButtons: Array containing one or more JSON objects with asset names and x,y offsets
  • continue: boolean
When the user clicks on anything, the client issues a POST request for /api/update with the following keys:
  • token: previously seen token
  • action: doAction, dialogueAction (named method on the server?)
  • parameter: next, dialogue:intro-doubt, dialogue:intro-principal-2, sign, intro-after-college, event:intro-12, (additional parameters to pass to that method?)
The API responds with a JSON object with the same keys as seen above (to start)

At some point along the line, the API responds to POST requests for /api/update with the following keys:
  • state: location
  • day: 1 (or 0?)
  • datetime: 14:00 SA 29 (literal string representing the date and time)
  • location: background image name
  • locationDescription: LIVING ROOM (literal name of the location)
  • money: 0 (money on the character)
  • energy: 81 (energy of the character)
  • hunger: 81 (hunger of the character)
  • arousal: 5 (arousal of the character)
  • items: array containing JSON objects with the following keys
    • id: name of object
    • visible: true
    • state: string value (seen: :closed, )
  • movements: array containing JSON objects representing where the character can move to (left location menu)
  • places: array containing JSON objects representing sub spaces within the current area (right location menu)
  • characters: array containing JSON objects representing characters who are present I'm assuming?
  • sprites: array containing JSON objects representing sprites and where/how to display them on the screen.
  • activeAreas: array containing JSON objects representing active areas and where/how to display them.
 

Maid Lain

Well-Known Member
Modder
Game Developer
Apr 4, 2018
1,888
16,382
@NachoCheese
Nice work! Is your job related to networking or IT by any chance?

After all resources have been loaded, client issues a POST request for /api/status with the following keys:
  • id: a UUID. I'm assuming this is used to look up the user's information through the Patreon API.
The API responds with a JSON object with the following keys:
  • patron: 0 (Assuming boolean: if this user is a Patron or not)
  • pledge: 0 (Assuming pledge value)
  • version: 5 (Assuming minor version of the client)
I think that the UUID is decided/created by the client. So I think it should be possible to set a custom ID but I'm not really sure if that's useful for anything, I doubt it is.

The JSON "patreon, pledge, version" response is done by the NetworkHelper class -> SendStatusRequest(string id) method. Once the values are received the values are set in the registry and not used for anything else. So I'm 99% sure these values aren't related to deciding what content the user has unlocked.


The API responds with a JSON object with the following keys:
  • status: ok
  • token: (a 164 byte string that appears to have several Base64 encoded segments separated by the '.' character)
    • Segment 1: a 36 byte Base64 encoded JSON object with the following keys:
      • alg: HS256
      • typ: JWT
      • Note:
    • Segment 2: an 83 byte Base64 encoded JSON object with the following keys:
      • id: The previously seen UUID
      • iat: The number of seconds since the UNIX epoch.
    • Segment 3: a 43 byte string that appears to be random data. (this base64 decodes to 32 bytes, so this is quite likely)
  • saves: an array (empty)
  • patron: false (if the user is a patron or not)
  • pledge: 0 (the pledge level of the patron)
The client issues a POST request for /api/start with the following keys:
  • token: the previously seen token
When the user clicks on anything, the client issues a POST request for /api/update with the following keys:
  • token: previously seen token
The API responds with a JSON object with the same keys as seen above (to start)
I'm not sure where in the code the logic is for the first response in the quote above. I think it's related to the LoginResponse class -> Parse() method but I don't remember. If it is then I changed the patron and pledge amount as soon as the client received the response so the patron and pledge part aren't important.

So what are tokens used for? In the scripts.dll there is code for handling and I think creating tokens too, but it wasn't very clear what they were being used for.


Also if the user id is tied to a patreon account, you probably could change the code in the client to save to your personal patreon account user id but use a patron's user id to access the api. Not sure if multiple people using the same user id to access the api would screw with each other's games or not though.
 

NachoCheese

Newbie
Dec 10, 2017
95
136
Nice work! Is your job related to networking or IT by any chance?
Oh, a little of this. A little of that. :p

I think that the UUID is decided/created by the client. So I think it should be possible to set a custom ID but I'm not really sure if that's useful for anything, I doubt it is.
With that packet capture, the first time that a UUID passed across the network was from client to server, but I wanted to reset the VM I was testing with and check it's behavior from the start. (Maybe UUID is set upon initial connection and passed client to server as a way of identifying a unique client).

The JSON "patreon, pledge, version" response is done by the NetworkHelper class -> SendStatusRequest(string id) method. Once the values are received the values are set in the registry and not used for anything else. So I'm 99% sure these values aren't related to deciding what content the user has unlocked.
My guess was that the information is just displayed locally.

I'm not sure where in the code the logic is for the first response in the quote above. I think it's related to the LoginResponse class -> Parse() method but I don't remember. If it is then I changed the patron and pledge amount as soon as the client received the response so the patron and pledge part aren't important.
Most likely. I was surprised that the UUID was actually encoded into the token string. Digging into the patreon login process might shed more light on why this is handled this way. That's something I skipped deep diving into at the time as I was more interested in api/start and api/update calls when I captured these packets.

So what are tokens used for? In the scripts.dll there is code for handling and I think creating tokens too, but it wasn't very clear what they were being used for.
HTTP is inherently stateless, the tokens are definitely being used by the clients to uniquely identify themselves to the server. This would be a requirement if game state is maintained on the server, as the server would need to know *which* game instance performed a given action (which is further supported by the content of the messages being passed, the client is always just telling the server which action was performed, and all of the state data is coming down from the server each time an action is performed)

Also if the user id is tied to a patreon account, you probably could change the code in the client to save to your personal patreon account user id but use a patron's user id to access the api. Not sure if multiple people using the same user id to access the api would screw with each other's games or not though.
As far as I can tell, saving on the server is likely just marking a game state as more persistent than every other game state it keeps track of. While it could keep that data in memory within the node.js process, it's probably a much better idea if it's pushing that state all the way back to a persistent database and then just updating as it goes. That would also mean that DS can restart the server without screwing over everyone who's currently playing. As for how saves are specifically triggered server-side, I never dug into that.
 

NachoCheese

Newbie
Dec 10, 2017
95
136
@Nach0Cheese @Maim Lain
Really, i don’t know what you’re talking about. :) But it sounds good. Does DS have built a Fort Knox?
Yes and no. Based on my observations, there's nothing you can do to the client to obtain access to the current version of the game. The server is another matter entirely though, I just don't have the time or patience to attempt to emulate it, and I draw the line at attempting to hack into it.
 
  • Like
Reactions: KaiserST

elvergallarga

New Member
Jun 30, 2017
6
0
There is a bit of a grind, but it's not like BB. In BB, you had all those scenes where you had a low chance of success until you built up a lot of persuasion skills, etc. Remember how you had to play for days before getting "lucky" just for Alice to let you rub her feet? There isn't anything like that.

It's repetitive at first in that you get up every day and go to class and talk with the students, then come home and talk with Julia, but each day there are new dialogues. And remember how in BB when you opened the door when Lisa was changing she would say the same thing each time? In this game when you spy on Julia in the shower or when she catches you watching porn, the dialogues change and develop for awhile before they repeat. Eventually your day will be going to class, then going to work as a maid, then going to the cafe to learn more about Lisa, then going home, but again, each day is a bit different until the main storyline with the principal is finished in this version.

It does look like there will be lots of stuff to buy in the future, plus homework to do and probably Kate will need to get fit in the gym, so eventually it could be more of a grind in that you'll have to repeat a lot of tasks over and over without any new scenes for days and days to unlock scenes, but so far that isn't the case.

Wow thanks!
I'll give it a try then
 

Pillowgirl

Newbie
Oct 3, 2017
66
43
The last few posts about investigating how the game works are seriously more entertaining than the actual game itself...
I came here from the milfycity thread when someone mentioned DS, and honestly i'm facepalming at seeing a unity game with online copyprotection, it reminds me of Diablo III and the people working to build an emulator on irc and i personally supplying them with a beta key to capture packets and reverse engineer a server.

Those were good times with lots of shenanigans and jokes about calling it EMUlator based on the bird.
 

NachoCheese

Newbie
Dec 10, 2017
95
136
honestly i'm facepalming at seeing a unity game with online copyprotection, it reminds me of Diablo III and the people working to build an emulator on irc and i personally supplying them with a beta key to capture packets and reverse engineer a server.
If I had the free time and if the game were actually worth emulating, that's how I'd go about solving this problem. Unfortunately, so far this game is only worth its renders and those are given away in the second API call.
 

Hlextor

Well-Known Member
May 6, 2017
1,655
4,972
If I had the free time and if the game were actually worth emulating, that's how I'd go about solving this problem. Unfortunately, so far this game is only worth its renders and those are given away in the second API call.
So maybe we‘ll see the first pussy (though with DS unlikely :rolleyes:) ... but if we‘ll see some day more sex stuff and the story is getting better, maybe you can think about to hack the game?! ;)
 

erer

New Member
May 9, 2017
6
0
Hi dudes!

Does 1$ patron get 0.5 content? I have hotel scenes, but not cafe yet and I have played like 2 or 3 months in game time. :confused:

Edit: And didin't get massage parlor in map, even Lien said about that.
 

Maid Lain

Well-Known Member
Modder
Game Developer
Apr 4, 2018
1,888
16,382
I wrote some kind of guide for young hackers. Enjoy.
I wouldn't completely disable the file checking in the assembly dll and would instead point the game to use a copy of the scripts.dll so the game can still update other files. I explained it a bit in a post on the previous page in this thread. But it probably doesn't matter too much though.
 

paloompa

Member
Jul 4, 2018
136
46
nice game but a bit grindy like the abandoned BB ... even characters from BB apper in it but nicely done
 
2.60 star(s) 184 Votes