Reverse Engineering - RewardedIvan/3DPS GitHub Wiki
whas upp???
Every request is sent to http://delugedrop.com/3Dash/whatever with http v1 and your favorite certified by robtop php security
> POST /push_level_data.php
> Content-Type: application/x-www-form-urlencoded
># URL Encoded Forms data:
> name = "self explanatory"
> author = "why not make an account system"
> difficulty = "0-5"
> data = {"name":"normally the limit is 24 chars","author":"same here","difficulty":0-5,"songId":0-21,"songStartTime":0-songlength,"floorId":0-3,"backgroundId":0-2,"startingColor":[red,green,blue],"levelData":[#Level data],"pathData":[#Path Data],"cameraData":[#Camera Data]}
private void PopulateRecentLevels(string data)
{
string[] array = data.Split("\n", StringSplitOptions.None);
for (int i = 0; i < array.Length; i += 4)
{
int id = int.Parse(array[i]);
string levelName = array[i + 1];
string author = array[i + 2];
int difficulty = int.Parse(array[i + 3]);
this.AddButton(this.recentContent, id, levelName, author, difficulty);
}
}
> GET /get_recent.php
< Level ID
< Level Name
< Level Author
< Level Difficulty
< Repeat.............
> POST /get_json.php certified robtop POST request
> Content-Type: application/x-www-form-urlencoded
># URL Encoded Forms data:
> id = 0-yes
< #Level Data (in json)
Pretty much every function mentioned here uses this class
public class Level
{
// Token: 0x04000088 RID: 136
public string name = "default";
// Token: 0x04000089 RID: 137
public string author = "default";
// Token: 0x0400008A RID: 138
public int difficulty;
// Token: 0x0400008B RID: 139
public int songId;
// Token: 0x0400008C RID: 140
public int songStartTime;
// Token: 0x0400008D RID: 141
public int floorId;
// Token: 0x0400008E RID: 142
public int backgroundId;
// Token: 0x0400008F RID: 143
public int[] startingColor;
// Token: 0x04000090 RID: 144
public int[] levelData;
// Token: 0x04000091 RID: 145
public int[] pathData;
// Token: 0x04000092 RID: 146
public int[] cameraData;
}
public static int[,] FlatDataToEditorData(List<GameObject>[][] inData, int totalItems)
{
int[,] array = new int[totalItems, 5];
int num = 0;
for (int i = 0; i < inData[0].Length; i++)
{
for (int j = 0; j < inData.Length; j++)
{
List<GameObject> list = inData[j][i];
for (int k = 0; k < list.Count; k++)
{
FlatItem component = list[k].GetComponent<FlatItem>();
array[num, 0] = component.index;
array[num, 1] = component.x;
array[num, 2] = component.y;
array[num, 3] = component.z;
array[num, 4] = component.angle;
num++;
}
}
}
return array;
}
Yep, one of the many numbers in a single array would look like [index, x, y, z, angle]
remove the brackets and continue it with every object and you get the level data
TODO
public static void SaveLevel()
{
SaveSelect.SaveFile(LevelEditor.ExportToLevelObject(), LevelEditor.currentSave);
}
This function gives info to this function.
public static void SaveFile(Level level, string number)
{
string path = SaveSelect.GetPath(number);
FileStream fileStream;
if (File.Exists(path))
{
fileStream = File.OpenWrite(path);
}
else
{
fileStream = File.Create(path);
}
new BinaryFormatter().Serialize(fileStream, level);
fileStream.Close();
}
This function writes to a file using the BinaryFormatter
class and the Serialize
method.
public static Level LoadFile(string number)
{
string path = SaveSelect.GetPath(number);
if (File.Exists(path))
{
FileStream fileStream = File.OpenRead(path);
Level result = (Level)new BinaryFormatter().Deserialize(fileStream);
fileStream.Close();
return result;
}
Debug.LogError("File not found");
return null;
}
Basically the same thing, just Deserialize
ing it.
How the fuck do we turn this shit into JSON???
Well obviously just use the same class in a diffrent c# app.
private void RecordArm()
{
float[] array = new float[4];
Vector3 myEulerAngles = this.boomArm.myEulerAngles;
array[0] = myEulerAngles.x;
array[1] = myEulerAngles.y;
array[2] = myEulerAngles.z;
array[3] = this.time;
CameraAnimator.recordedPoints.Add(array);
}
This function is called every frame update if the "playtester" has not ended and you haven't pressed escape.
This is pretty similar to the #Level Data, but its more like [x, y, z, time]
and
continue with every angle squish it in to one array and ya done
public static Level ExportToLevelObject()
{
return new Level
{
name = LevelEditor.levelName,
author = LevelEditor.levelAuthor,
difficulty = LevelEditor.difficulty,
songId = LevelEditor.songId,
songStartTime = LevelEditor.songStartTime,
floorId = LevelEditor.floorId,
backgroundId = LevelEditor.backgroundId,
startingColor = LevelEditor.ColorToArray(LevelEditor.startingColor),
levelData = LevelEditor.GridToArray(LevelEditor.levelData),
pathData = LevelEditor.GridToArray(LevelEditor.pathData),
cameraData = LevelEditor.GridToArray(LevelEditor.cameraData)
};
}
This gets converted to JSON
public string LevelToJSON(Level level)
{
return JsonUtility.ToJson(level);
}
And gets hand crafted in to a request, also is it just me or did delugedrop forget that the name, author and difficulty is also in the Level
class??
private IEnumerator SetRequest(string uri, string levelName, string levelAuthor, int difficulty, string JSON)
{
WWWForm wwwform = new WWWForm();
wwwform.AddField("name", levelName);
wwwform.AddField("author", levelAuthor);
wwwform.AddField("difficulty", difficulty);
wwwform.AddField("data", JSON);
using (UnityWebRequest www = UnityWebRequest.Post(uri, wwwform))
{
yield return www.SendWebRequest();
int responseCode;
if (www.result == UnityWebRequest.Result.ConnectionError || www.result ==UnityWebRequest.Result.DataProcessingError || www.result ==UnityWebRequest.Result.ProtocolError)
{
Debug.Log(www.error);
responseCode = 0;
}
else
{
Debug.Log("No Unity Errors");
responseCode = (int)www.responseCode;
}
this.ManageOutput(www.downloadHandler.text, responseCode);
}
UnityWebRequest www = null;
yield break;
yield break;
}