it's json.. i would say.. you just parse it as json?
Code:var json = System.IO.File.ReadAllText(@"d:\test.json"); var objects = JArray.Parse(json); // parse as array
Intralism-Bot.EXE
Someone else who helped me a lot with ideas & I worked on some sort of Bot the past 2 days. It was pretty head breaking. :D
Since we are the very first ones working on a bot for it made in C# there is no base technique we could use.
There was once a Russian who made one. I contacted him and found out that it was made with pixel color detections.
I thought about using the same techniques as for Osu a very long time till we started.
In Short:
1) Getting the current song through memory reading.
2) Opening the right file based on the current song. (Where all the pieces of information from the map are written down)
3) Converting it trough Readline functions into a for us useful list.
4) Checking by a time offset when to click.
5) Hooking the keyboard.
What we had to fight with:
It isn't possible to get the current map/song trough memory reading since the game "Intralism" doesn't have a method like that.
The Game got made in Unity so I was able to find that out after I tried finding it with Cheat Engine. Sadly they have used a strong Obfuscation a few weeks afterward. And there is now way to compile it now. Else I would make my own one. Sure. You can use de4dot or other deobfuscators. But the game is unplayable afterwards.
Fine. I decided to use a combo box for it instead. So the user can select the current map himself.
The next one was easy due to the combo box I included.
Converting the config was pretty decent. I nearly raged at this point.
Using the Readline function & the split function wouldn't be enough. It didn't work.
So the one who worked with me had suddenly an awesome Idea using Regular Expressions.
It got that option to look for a pattern.
I know that this looks terrible. But it is the first version and I hadn't thought about cleaning the code before since the Bot isn't finished yet.
The next step was easy again. Since we added only the time & what to press to the list "timepoints" we could use the information from now on.Code:[...] using System.Text.RegularExpressions; [...] List<string> config = new List<string>(); List<string> timepoints = new List<string>(); string path = @"C:\Program Files (x86)\Steam\steamapps\workshop\content\513510\1282 767793\config.txt"; bool fertig = false; string s = ""; [...] private void ConfigOpener() { using (StreamReader sr = File.OpenText(path)) { while ((s = sr.ReadLine()) != null) { config.Add(s); } } fertig = true; AddTimepoints(); } [...] private void AddTimepoints() { if (fertig == true) { string pattern = @"{""time"":([0-9]*\.[0-9]*),""data"":\[""SpawnObj"",""\[([a-z-]*)]""]}"; string input = ""; foreach (string item3 in config) { input = input + item3; } RegexOptions options = RegexOptions.Multiline | RegexOptions.IgnoreCase; foreach (Match m in Regex.Matches(input, pattern, options)) { timepoints.Add(m.Groups[1].ToString()); timepoints.Add(m.Groups[2].ToString()); } } ActualBot(); } [...]
It would look like this imaginary:
the_list = [time_1, what_to_press_1, time_2, what_to_press_2, time_3, what_to_press_3, ...] and so on.
We could output it somehow else and make it look like this technically:
But I think it wouldn't make any differs.time_1
what_to_press_1
time_2
what_to_press_2
time_3
what_to_press_3
...
Here comes the next small problem. There is no time offset. The game got no sort of timer for the songs like Osu does. So I tried doing it with some timer at first. But the tick rate isn't fast enough and isn't constantly enough for me. So I used "sleep" instead. Didn't worked out well.
So why did I created this thread?
This community is creative. And there are very skilled coders here. I can't reach that skill at this point and got less knowledge than them.
My Question is: "How would you solve this?"
I clearly got no ideas anymore at this point.
Thanks in advance! I would also credit the one whose method I will use.
#LOGS
12-02-2020 ⌨ [MPGH]defaulto got gifted the Premium Membership from [MPGH]Azuki - sponsored by [MPGH]Flengo.
27-11-2019 ⌨ [MPGH]defaulto captured the GFX Team Base together with [MPGH]Howl & [MPGH]Poonce.
08-14-2017 ⌨ defaulto joined the game.
it's json.. i would say.. you just parse it as json?
Code:var json = System.IO.File.ReadAllText(@"d:\test.json"); var objects = JArray.Parse(json); // parse as array
Hello, I'm the guy who suggested making use of RegEx.
OP has already successfully parsed the times and input directions but is unsure how he should implement them to make a bot functional.
He basically has it listed as strings like this atm:
(Idk his exact code but...)Code:time //called by timepoints[0] input //called by timepoints[1] time //timepoints[2] input //... ...
He's struggling with setting up a proper accurate timer to use and with effectively using the time and input together to get a bot to run properly.
So far I know he tried using InputSimulator but hasn't gotten it to work the way he meant it to.
Last edited by Efilon; 02-10-2019 at 03:47 PM.
the time is for sure findable with cheat engine then your Thread can just read constantly the Game Timer and if the actual time needs a keypress, then you send it.
All what you need to find out is, what keysending the game is accepting.
Some Application just need the Window Messages, then you can just send a PostMessage to the Window.
If not, you need to simulate a keypress with SendInput. The Trick that the Window accept it propper is not to send the key and key up immidiatly, it needs some ms timeout. How much depends on the Target Process
I will try to find it again then.
Is there a proper way on how to check if the time value from the adress is the one on the list? Which, after the time has passed jumps to the next timestamp? Or is there a better way to handle this and maybe preprocess this?
I looked into resources like Blackmagic where all the parsers for the .osk files are, calculating stuff, etc.
I haven't found a method which checks this yet. Some Pseudocode would be great.
Last edited by defaulto; 02-11-2019 at 06:56 AM. Reason: Addition.
From which Game exactly we are even talking about here, if not OSU? Is it for free? then i may can help
#LOGS
12-02-2020 ⌨ [MPGH]defaulto got gifted the Premium Membership from [MPGH]Azuki - sponsored by [MPGH]Flengo.
27-11-2019 ⌨ [MPGH]defaulto captured the GFX Team Base together with [MPGH]Howl & [MPGH]Poonce.
08-14-2017 ⌨ defaulto joined the game.
Thanks to everyone at this point for trying to help me/us.
I've found the solution I was looking for. It's still a bit inaccurate but I think I am on the right way.
Looked again in Afex his Source and found these lines hidden between other lines.
Changed it so it works for us. Since there is still no time offset.
(Or I am just someone who can't look for a Float in CE which is increasing by time.)
This will start this indeed. The use of Input Simulator will be changed very soon to actual Keyboard Hooking.Code:private void Hotkey(object sender, HotkeyEventArgs e) // This is a temporary solution since there is no in-game timer yet. { switch (e.Name) { case "Start": _playing = !_playing; if (_playing) { _relaxThread = new Thread(new ThreadStart(RelaxThread)) { IsBackground = true }; _relaxThread.Start(); timer1.Start(); // This is for updating the Form stopwatch.Start(); // This is a temporary-solution since there is no ingame timer yet. } else { _relaxThread.Abort(); _relaxThread = null; timer1.Stop(); stopwatch.Stop(); } break; } e.Handled = true; }
Code:private Thread _relaxThread; private bool _playing = false; private int TimingTime; private string WhatToPress; InputSimulator sim = new InputSimulator(); private void RelaxThread() { while (_playing) { if (_playing) { for (int i = 0; i < timepoints1.Count(); i++) { TimingTime = (int)float.Parse(timepoints1[i]); MessageBox.Show(timepoints1[i]); // Testing Purpose MessageBox.Show(TimingTime.ToString()); // Testing Purpose while (stopwatch.Elapsed.TotalMilliseconds * 10000 < TimingTime) { Thread.Sleep(1); } MessageBox.Show(currenttime); WhatToPress = timepoints2[i]; if (WhatToPress == "Up") { sim.Keyboard.KeyUp(WindowsInput.Native.VirtualKeyCode.VK_W); metroTextBox1.AppendText("Clicked Up-Arc at: " + currenttime + "ps\n"); } else if (WhatToPress == "Right") { sim.Keyboard.KeyUp(WindowsInput.Native.VirtualKeyCode.VK_D); metroTextBox1.AppendText("Clicked Right-Arc at: " + currenttime + "ps\n"); } else if (WhatToPress == "Down") { sim.Keyboard.KeyUp(WindowsInput.Native.VirtualKeyCode.VK_S); metroTextBox1.AppendText("Clicked Down-Arc at: " + currenttime + "ps\n"); } else if (WhatToPress == "Left") { sim.Keyboard.KeyUp(WindowsInput.Native.VirtualKeyCode.VK_A); metroTextBox1.AppendText("Clicked Left-Arc at: " + currenttime + "ps\n"); } } } else { break; } } }
#LOGS
12-02-2020 ⌨ [MPGH]defaulto got gifted the Premium Membership from [MPGH]Azuki - sponsored by [MPGH]Flengo.
27-11-2019 ⌨ [MPGH]defaulto captured the GFX Team Base together with [MPGH]Howl & [MPGH]Poonce.
08-14-2017 ⌨ defaulto joined the game.
sorry, before i didn't found the time to try it out, i thought honestly it would be a lil bit harder, but it took me 10 minutes
Address is:
"UnityPlayer.dll"+013EC890 -> 100 -> 500 -> 5c8 -> 54
it's an accurate timer which everytime change if there is some "rythm" tone
On which Version did you find this? I am interested since it doesn't make sense to me by now.
Or what do you mean by there is a change every "rythm"?
Only these Bytes are changing and the integer to it seems to be some sort of timer.
The Value of the adress is mostly blank. (-> ???)
Or I have set the pointer to it wrong.
Still thanks for finding this. Appreciate it.
Might be useful? ^^
#LOGS
12-02-2020 ⌨ [MPGH]defaulto got gifted the Premium Membership from [MPGH]Azuki - sponsored by [MPGH]Flengo.
27-11-2019 ⌨ [MPGH]defaulto captured the GFX Team Base together with [MPGH]Howl & [MPGH]Poonce.
08-14-2017 ⌨ defaulto joined the game.
if you want a function and "indirect" pointer i guess.
"UnityPlayer.dll"+A7EF66 (mov [r10],eax) r10 = address to timer
you can put a breakpoint there and get the register.
since it's a unity game, i'd recommend just hooking onto somewhere around the GameScene class
GameScene.calculatedmaptime should interest you.
good luck on your journey, i'll be here for further questions
to create more confusion
- - - Updated - - -
Here's a few you could try:3 @defaulto
"UnityPlayer.dll"+0146CF00 -> 88 -> 1A0 -> C0 -> 28 -> 120 (Type Float)
"UnityPlayer.dll"+0146CF00 -> 140 -> 1A0 -> C0 -> 28 -> 120 (Type Float)
"UnityPlayer.dll"+0146CF00 -> 180 -> 1A0 -> C0 -> 28 -> 120 (Type Float)
"UnityPlayer.dll"+0146CF00 -> 180 -> 1A0 -> 60-> 28 -> 120 (Type Float)
Okay change of plan, don't use my offsets, or the other persons.
The game GC's every time a new map is loaded or the mode is switched from Relax to Normal.
Making the offsets useless.
edit:
but guess who got it work anyway lolol.
UnityPlayer.dll gc's the scene, but there's stuff in mono.dll that's handling something related to the gamescene, just point to that
defaulto (02-19-2019),Efilon (02-19-2019),MikeRohsoft (02-26-2019)