void Check_Game_Running() { Thread.CurrentThread.Name = "Memory_Thread_Check_Game_Running"; bool was_running = true; while (true) { Thread.Sleep(1000); Process[] pname = Process.GetProcessesByName(Game_Name); if ((pname.Length != 0) != (was_running)) { was_running = !was_running; if (was_running) { Notification_Message?.Invoke(this, new StringArg("Game was opened")); GameOpened?.Invoke(this, new EventArgs()); } else { Notification_Message?.Invoke(this, new StringArg("Game was closed")); GameClosed?.Invoke(this, new EventArgs()); } } } }
private void Init_SexLabAnimations() { string sexlab_dir = Game_Path + @"\FunScripts\SexLab"; string[] mod_dirs = Directory.GetDirectories(sexlab_dir); foreach (string mod_dir in mod_dirs) { if (mod_dir.ToLower() == "o****m") { SexLab_Orgasm_Event = new Actor_Data("o****m", mod_dir); continue; } string[] animation_dirs = Directory.GetDirectories(mod_dir); foreach (string animation_dir in animation_dirs) { string name = Path.GetFileName(animation_dir).ToLower(); SexLab_Animations.Add(new Animation_Data(name, animation_dir)); } } int funscript_count = 0; foreach (Animation_Data sl_a in SexLab_Animations) { foreach (Stage_Data s_d in sl_a.stages) { if (s_d == null) { continue; } foreach (Actor_Data p_d in s_d.positions) { if (p_d == null) { continue; } foreach (BodyPart_Data b_d in p_d.bodyparts) { if (b_d == null) { continue; } foreach (EventType_Data e_d in b_d.eventTypes) { funscript_count++; } } } } } Notification_Message?.Invoke(this, new StringArg(String.Format("Registered {0} SexLab animations, with a total of {1} funscripts", SexLab_Animations.Count, funscript_count))); }
private void Check_Timer() { Thread.CurrentThread.Name = "Memory_Thread_Check_Timer"; float old_timer = 0; DateTime old_time = DateTime.Now; bool gamePaused = false; while (true) { Thread.Sleep(10); //get animation timer float timer = memory.ReadFloat(timer_offsets); DateTime time = DateTime.Now; if (timer < old_timer) { AnimationTimeResetted?.Invoke(this, EventArgs.Empty); } if (timer != old_timer) { AnimationTimeUpdated?.Invoke(this, new FloatArg(timer)); } if (timer == old_timer) { if (!gamePaused) { if (time > old_time + new TimeSpan(0, 0, 0, 0, 150)) { gamePaused = true; Notification_Message?.Invoke(this, new StringArg("Game paused")); GamePaused?.Invoke(this, EventArgs.Empty); } } } else { if (gamePaused) { gamePaused = false; Notification_Message?.Invoke(this, new StringArg("Game resumed")); GameResumed?.Invoke(this, EventArgs.Empty); } old_time = time; } old_timer = timer; } }
public List <Running_Event> PlayEvent(string name) { name = name.ToLower(); foreach (Actor_Data event_data in events) { if (event_data.name == name) { List <Running_Event> runningEvents = PlayEvent(event_data); Notification_Message?.Invoke(this, new StringArg(String.Format("Playing event: {0} ({1})", name, runningEvents.Count))); return(runningEvents); } } Warning_Message?.Invoke(this, new StringArg("Count not find: " + name)); return(new List <Running_Event>()); }
private void Init_Events() { string other_dir = Game_Path + @"\FunScripts"; string[] mod_dirs = Directory.GetDirectories(other_dir); foreach (string mod_dir in mod_dirs) { if (Path.GetFileName(mod_dir).ToLower() == "sexlab") { continue; } string[] event_dirs = Directory.GetDirectories(mod_dir); foreach (string event_dir in event_dirs) { string name = Path.GetFileName(event_dir).ToLower(); events.Add(new Actor_Data(name, event_dir)); } } int funscript_count = 0; foreach (Actor_Data p_d in events) { if (p_d == null) { continue; } foreach (BodyPart_Data b_d in p_d.bodyparts) { if (b_d == null) { continue; } foreach (EventType_Data e_d in b_d.eventTypes) { funscript_count++; } } } Notification_Message?.Invoke(this, new StringArg(String.Format("Registered {0} lose events, with a total of {1} funscripts", events.Count, funscript_count))); }
private void StartCustomEvent(int customId, string eventName) { Notification_Message?.Invoke(this, new StringArg("Custom Event Start: " + eventName)); CustomRunningEvents.Add(new CustomRunningEvent(customId, vibrationEvents.PlayEvent(eventName))); }
public void Run() { Thread.Sleep(100); string path = Game_Path + @"\FunScripts\link.txt"; const Int32 BufferSize = 128; using (var fileStream = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (var streamReader = new StreamReader(fileStream, Encoding.UTF8, true, BufferSize)) { long line_nr = 0; bool loading_game = true; bool skipping_old = true; while (true) { String line = streamReader.ReadLine(); if (line == null) { skipping_old = false; //we skipped all old lines Thread.Sleep(10); } else { line_nr++; line = line.ToLower().Replace("\'", "\""); //Console.WriteLine(line); if (!line.StartsWith("{")) { Debug_Message?.Invoke(this, new StringArg(String.Format("ESP msg - {0}", line))); continue; } ; JObject json; try { json = JObject.Parse(line); } catch { Warning_Message?.Invoke(this, new StringArg(String.Format("Couldn't format line {0}: {1}", line_nr, line))); continue; }; string mod_property = (string)json.Property("mod"); string event_property = (string)json.Property("event"); string type_property = (string)json.Property("type"); //this code runs mainly purpose is to skip old lines of code in the event file if (loading_game || skipping_old) { bool allowed = false; if (mod_property == "game") { if (event_property == "loading save" || event_property == "loading save done") { allowed = true; } } if (mod_property == "dd") { if (event_property == "(de)equiped") { allowed = true; } } if (mod_property == "sla") { allowed = true; } if (!allowed) { continue; } } switch (mod_property) { case "game": switch (event_property) { case "damage": break; case "loading save": loading_game = true; string mods_found = ""; if ((bool)json.Property("sla_running")) { mods_found += "- SexLab Arousal\n"; } if ((bool)json.Property("dd_running")) { mods_found += "- Deviouse Devices\n"; } if ((bool)json.Property("mme_running")) { mods_found += "- Milk Mod Economy\n"; } if ((bool)json.Property("bf_running")) { mods_found += "- Being Female\n"; } if ((bool)json.Property("sgo_running")) { mods_found += "- Soul Gem Oven\n"; } Notification_Message?.Invoke(this, new StringArg("Loading save game")); Save_Loaded?.Invoke(this, new StringArg(mods_found)); break; case "loading save done": loading_game = false; Notification_Message?.Invoke(this, new StringArg("Save game Loaded")); break; case "menu opened": //TODO might need to re add this if the animation timer based check doest work good enough //form_EventFileReader.GamePaused(true); inMenu = true; break; case "menu closed": //form_EventFileReader.GamePaused(false); inMenu = false; break; } break; case "sla": arousal = (int)json.Property("arousal"); Arousal_Updated?.Invoke(this, new IntArg(arousal)); break; case "dd": switch (event_property) { case "(de)equiped": string[] devices_names = new string[Enum.GetNames(typeof(DD_Device_Location)).Length]; //check which device was (de)equiped for (int i = 0; i < dd_devices.Length; i++) { DD_Device_Type dd_device_current_type = dd_devices[i]; string s_location = Enum.GetNames(typeof(DD_Device_Location))[i].ToLower(); string s_location_type = (string)json.Property(s_location); string[] s_location_types = Array.ConvertAll(Enum.GetNames(typeof(DD_Device_Type)), d => d.ToLower()); DD_Device_Type dd_device_new_type = (DD_Device_Type)Array.IndexOf(s_location_types, s_location_type); //check if this was the device that changed //And we dont run any event when the game was loading if (!(loading_game || skipping_old) && dd_device_current_type != dd_device_new_type) { //check if device was added or removed if (dd_device_new_type != DD_Device_Type.none) { //device was removed Notification_Message?.Invoke(this, new StringArg("Deviouse Device equiped: " + s_location + " " + s_location_type)); vibrationEvents.PlayEvent("dd device equiped " + s_location); } else { //device was added Notification_Message?.Invoke(this, new StringArg("Deviouse Device de-equiped: " + s_location + " " + s_location_type)); vibrationEvents.PlayEvent("dd device de-equiped " + s_location); } //break; } dd_devices[i] = dd_device_new_type; devices_names[i] = s_location_type; } DD_Device_Update?.Invoke(this, new StringArgs(devices_names)); break; case "vibrate effect start": System.Diagnostics.Debug.WriteLine("---PRIORITY---"); System.Diagnostics.Debug.WriteLine("Devious Device vibrate START" + (float)json.Property("arg")); System.Diagnostics.Debug.WriteLine("---ENDPRIORITY---"); float arg = (float)json.Property("arg"); StartCustomEvent(CustomEventIdDdVibrate, LookupEventName(arg)); Notification_Message?.Invoke(this, new StringArg("Devious Device vibrate " + arg)); break; case "vibrate effect stop": System.Diagnostics.Debug.WriteLine("---PRIORITY---"); System.Diagnostics.Debug.WriteLine("Devious Device vibrate STOP" + (float)json.Property("arg")); System.Diagnostics.Debug.WriteLine("---ENDPRIORITY---"); StopCustomEvent(CustomEventIdDdVibrate); Notification_Message?.Invoke(this, new StringArg("Devious Device vibrate stop " + (float)json.Property("arg"))); break; case "o****m": Notification_Message?.Invoke(this, new StringArg("Deviouse Device o****m " + (float)json.Property("arg"))); break; case "edged": Notification_Message?.Invoke(this, new StringArg("Deviouse Device edged " + (float)json.Property("arg"))); StopCustomEvent(CustomEventIdDdVibrate); // stop vibration effect already here break; case "device event": string type = (string)json.Property("type"); Notification_Message?.Invoke(this, new StringArg("Deviouse Device event: " + type)); switch (type) { case "trip over": break; case "drip": break; case "stamina drain": break; case "blindfold mystery": break; case "restraints+armor": break; case "posture collar": break; case "wet padding": break; case "blindold trip": break; case "nipple piercings": break; case "tight corset": break; case "plug moan": break; case "trip and fall": break; case "bump pumps": break; case "struggle": break; case "belted empty": break; case "mounted": break; case "tight gloves": break; case "bra chafing": break; case "periodic shock": break; case "arm cuff fumble": break; case "draugr plug vibration": break; case "restrictive collar": break; case "mana drain": break; case "vibration": break; case "harness": break; case "horny": break; case "chaos plug": break; case "belt chafing": break; case "health drain": break; case "organicvibrationeffect": break; default: Warning_Message?.Invoke(this, new StringArg("Deviouse Device event unknown type: " + type)); break; } break; } break; case "sexlab": string name = (string)json.Property("name"); switch (event_property) { case "animation started": case "animation changed": { int stage = (int)json.Property("stage") - 1; int position = (int)json.Property("pos"); bool usingStrapon = (bool)json.Property("usingstrappon"); string[] tags = json.Property("tags").Value.ToObject <string[]>(); Notification_Message?.Invoke(this, new StringArg("SexLab " + event_property + " : \"" + name + "\" stage:" + stage + " position: " + position + " using strapon: " + usingStrapon)); bool found = vibrationEvents.SexLab_StartAnimation(name, stage, position, usingStrapon); if (!found) { Notification_Message?.Invoke(this, new StringArg("Using Generic event")); vibrationEvents.SexLab_StartAnimation("Generic", stage, 0, false); } if (event_property == "animation changed") { vibrationEvents.SexLab_Update_Event(); } } break; case "animation ended": Notification_Message?.Invoke(this, new StringArg("SexLab animation stopped")); vibrationEvents.SexLab_StopAnimation(); break; case "stage started": { int stage = (int)json.Property("stage") - 1; Notification_Message?.Invoke(this, new StringArg("SexLab stage started: " + stage)); vibrationEvents.SexLab_SetStage(stage); } break; case "position changed": { int position = (int)json.Property("pos"); Notification_Message?.Invoke(this, new StringArg("SexLab position changed: " + position)); vibrationEvents.SexLab_SetPosition(position); } break; case "o****m started": Notification_Message?.Invoke(this, new StringArg("SexLab o****m")); vibrationEvents.SexLab_Start_Orgasm(); break; case "o****m ended": Notification_Message?.Invoke(this, new StringArg("SexLab o****m ended")); vibrationEvents.SexLab_Stop_Orgasm(); break; } break; case "mme": int mpas = (int)json.Property("mpas"); int milkingType = (int)json.Property("milkingtype"); switch (event_property) { case "StartMilkingMachine": break; case "StopMilkingMachine": break; case "FeedingStage": break; case "MilkingStage": break; case "FuckMachineStage": break; } break; case "custom": int id = (int)json.Property("type"); if (event_property == "start") { StartCustomEvent(id, type_property); } else { StopCustomEvent(id); } break; } } } } }
private IntPtr Inject_SkyrimVR() { int len = 6; int data_offset = 0x100; byte[] bytes_program = { 0x48, 0x8B, 0xF2, //mov rsi,rdx <-newmem 0x48, 0x8B, 0x39, //mov rdi,[rcx] 0x51, 0x50, 0x48, 0xB8, 0x00, 0x00, 0xEC, 0x4E, 0xF7, 0x7F, 0x00, 0x00, //mov rax,SkyrimSE.exe SkyrimSE.exe 0x48, 0x05, 0x68, 0x96, 0xF8, 0x01, // 1st offset 0x48, 0x8B, 0x00, //mov rax,[rax] 0x48, 0x05, 0xD0, 0x00, 0x00, 0x00, // 2th offset 0x48, 0x8B, 0x00, //mov rax,[rax] 0x48, 0x83, 0xC0, 0x08, // 3th offset 0x48, 0x8B, 0x00, //mov rax,[rax] 0x48, 0x05, 0xA8, 0x01, 0x00, 0x00, // 4th offset 0x48, 0x8B, 0x00, //mov rax,[rax] 0x48, 0x05, 0x90, 0x00, 0x00, 0x00, // 5tffset 0x48, 0x8B, 0x00, //mov rax,[rax] 0x48, 0x83, 0xC0, 0x68, // 6tffset 0x4C, 0x39, 0xF0, 0x0F, 0x85, 0x39, 0x00, 0x00, 0x00, //jne finishUp 0x48, 0xB8, 0x8A, 0x00, 0xEB, 0xC4, 0xF7, 0x7F, 0x00, 0x00, //mov rax,randomData randomData 0x48, 0x05, 0xF0, 0x00, 0x00, 0x00, 0x48, 0x83, 0xC0, 0x10, // <-increaseArray 0x48, 0x39, 0x38, 0x0F, 0x84, 0x0E, 0x00, 0x00, 0x00, //je countUoArrayItem 0x83, 0x38, 0x00, 0x0F, 0x84, 0x02, 0x00, 0x00, 0x00, //je createNewArrayItem 0xEB, 0xE8, //jmp increaseArray <-createNewArrayItem 0x48, 0x89, 0x38, // <-countUpArrayItem 0x48, 0x83, 0xC0, 0x08, 0x48, 0x8B, 0x08, 0x48, 0x83, 0xC1, 0x01, 0x48, 0x89, 0x08, 0x58, //pop rax <-finishUp 0x59, //pop rcx 0xE9, 0x28, 0x1C, 0x1B, 0x00 //jmp INJECT INJECT // <-randomData }; AOB_Scanner.AOB_Scanner aob_scanner = new AOB_Scanner.AOB_Scanner(memory.process, memory.ProcessHandle, "48 8B C4 57 48 81 EC 40 01 00 00 48 C7 44 24 20 FE FF FF FF 48 89 58 10 48 89 70 18"); aob_scanner.setModule(memory.process.MainModule); IntPtr ptr_inject = (IntPtr)aob_scanner.FindPattern(); if (ptr_inject == IntPtr.Zero) { Notification_Message?.Invoke(this, new StringArg("Could not inject, did the game load past the main menu?")); return(IntPtr.Zero); } ptr_inject += 0x1C; //check if we already injected code byte b = memory.ReadByte(ptr_inject); if (b == 0xE9) { Notification_Message?.Invoke(this, new StringArg("Skipping injection (already injected)")); return((IntPtr)((long)memory.ReadInt32(ptr_inject + 0x1) + (long)ptr_inject) + 5 + bytes_program.Length + data_offset); } IntPtr ptr_functon = memory.AllocateMemory(10000, ptr_inject); IntPtr ptr_data = ptr_functon + bytes_program.Length; byte[] bytes = new byte[10000]; //write program Array.Copy(bytes_program, bytes, bytes_program.Length); ////////////////////////////////////////// /// Replace long jumps in the program ////////////////////////////////////////// //replace SkyrimSE.exe byte[] bytes_ptr_baseAddress = BitConverter.GetBytes((ulong)memory.process.MainModule.BaseAddress); for (int i = 0; i < 8; i++) { bytes[0x0A + i] = bytes_ptr_baseAddress[i]; } //replace randomData byte[] bytes_ptr_data = BitConverter.GetBytes((ulong)ptr_data); for (int i = 0; i < 8; i++) { bytes[0x4C + i] = bytes_ptr_data[i]; } //replace INJECT byte[] bytes_ptr_return = BitConverter.GetBytes((ulong)ptr_inject + (ulong)len - (ulong)ptr_functon - (ulong)0x8A); for (int i = 0; i < 4; i++) { bytes[0x86 + i] = bytes_ptr_return[i]; } memory.WriteBytes(ptr_functon, bytes); memory.Hook(ptr_inject, ptr_functon, len, true); return(ptr_data + data_offset); }
private IntPtr Inject_TESV() { int len = 5; int data_offset = 0x100; byte[] bytes_program = { 0x8B, 0xF0, 0x50, 0xB8, 0xA6, 0x00, 0xF1, 0x01, 0x83, 0xC0, 0x50, 0x89, 0x08, 0x8B, 0xC8, 0x83, 0xC1, 0x08, 0x58, 0x89, 0x01, 0x83, 0xC1, 0x08, 0x89, 0x11, 0x83, 0xC1, 0x08, 0x58, 0x89, 0x01, 0x83, 0xC1, 0x08, 0x58, 0x89, 0x01, 0x58, 0x8B, 0xD0, 0x50, 0x8B, 0x01, 0x50, 0x83, 0xE9, 0x08, 0x8B, 0x01, 0x50, 0x83, 0xE9, 0x08, 0xFF, 0x31, 0x83, 0xE9, 0x08, 0xFF, 0x31, 0x83, 0xE9, 0x08, 0xFF, 0x31, 0xB8, 0x00, 0x00, 0x40, 0x00, 0x05, 0x3C, 0x06, 0xF1, 0x00, 0x8B, 0x00, 0x83, 0xC0, 0x74, 0x8B, 0x00, 0x83, 0xC0, 0x04, 0x8B, 0x00, 0x05, 0x00, 0x01, 0x00, 0x00, 0x8B, 0x00, 0x83, 0xC0, 0x10, 0x8B, 0x00, 0x83, 0xC0, 0x38, 0x39, 0xC2, 0x0F, 0x85, 0x2C, 0x00, 0x00, 0x00, 0xB8, 0xA6, 0x00, 0xF1, 0x01, 0x05, 0xF0, 0x00, 0x00, 0x00, 0x83, 0xC0, 0x10, 0x39, 0x38, 0x0F, 0x84, 0x0D, 0x00, 0x00, 0x00, 0x83, 0x38, 0x00, 0x0F, 0x84, 0x02, 0x00, 0x00, 0x00, 0xEB, 0xEA, 0x89, 0x38, 0x83, 0xC0, 0x08, 0x8B, 0x18, 0x83, 0xC3, 0x01, 0x89, 0x18, 0x5A, 0x58, 0x58, 0x83, 0xFE, 0x04, 0xE9, 0x00, 0x00, 0x00, 0x00 }; AOB_Scanner.AOB_Scanner aob_scanner = new AOB_Scanner.AOB_Scanner(memory.process, memory.ProcessHandle, "8B 44 24 04 81 EC 08 01 00 00 53 56 57 8B 38 8B C7 32 DB 8D 50 01 8A 08 40 84 C9 75 F9 2B C2"); aob_scanner.setModule(memory.process.MainModule); IntPtr ptr_inject = (IntPtr)aob_scanner.FindPattern(); if (ptr_inject == IntPtr.Zero) { Error_Message?.Invoke(this, new StringArg("Could not inject, did the game load past the main menu?")); return(IntPtr.Zero); } ptr_inject += 0x1f; //check if we already injected code byte b = memory.ReadByte(ptr_inject); if (b == 0xE9) { Notification_Message?.Invoke(this, new StringArg("Skipping injection (already injected)")); return((IntPtr)((long)memory.ReadInt32(ptr_inject + 0x1) + (long)ptr_inject) + 5 + bytes_program.Length + data_offset); } IntPtr ptr_functon = memory.AllocateMemory(10000); IntPtr ptr_data = ptr_functon + 0xA6; byte[] bytes = new byte[10000]; //write program Array.Copy(bytes_program, bytes, bytes_program.Length); //some parts in the program are static addresses that need to be overwriten byte[] bytes_ptr_data = BitConverter.GetBytes((ulong)ptr_data); for (int i = 0; i < 4; i++) { bytes[4 + i] = bytes_ptr_data[i]; } for (int i = 0; i < 4; i++) { bytes[112 + i] = bytes_ptr_data[i]; } byte[] bytes_ptr_return = BitConverter.GetBytes((ulong)ptr_inject - (ulong)bytes_program.Length + (ulong)len - (ulong)ptr_functon); for (int i = 0; i < 4; i++) { bytes[162 + i] = bytes_ptr_return[i]; } memory.WriteBytes(ptr_functon, bytes); memory.Hook(ptr_inject, ptr_functon, len); return(ptr_data + 0x100); }
private void Check_Events() { Thread.CurrentThread.Name = "Memory_Thread_Check_Events"; List <AnimationItem> AnimationList = new List <AnimationItem>(); bool First_Check = true; while (true) { IntPtr ptr = ptr_data; Thread.Sleep(50); //check if events have played while (true) { IntPtr temp_debugging = ptr; IntPtr name_address = memory.ReadPointer(ptr); if (name_address == IntPtr.Zero) { break; } string name = memory.ReadString(name_address, 30); int amount = memory.ReadInt32(ptr + 0x8); bool found = false; foreach (AnimationItem a in AnimationList) { if (a.name == name) { found = true; if (a.amount != amount) { a.amount = amount;//update to new amount if (!First_Check) { Notification_Message?.Invoke(this, new StringArg(String.Format("Animation playing name: {0}", name))); Debug_Message?.Invoke(this, new StringArg(String.Format("Animation playing counter: {0}, address: 0x{1:X}, nameAddress: 0x{2:X}", amount, temp_debugging.ToInt64(), name_address.ToInt64()))); AnimationEvent?.Invoke(this, new StringArg(name)); } } break; } } if (!found) { AnimationList.Add(new AnimationItem(name, amount)); if (!First_Check) { Notification_Message?.Invoke(this, new StringArg(String.Format("Animation playing name: {0}", name))); Debug_Message?.Invoke(this, new StringArg(String.Format("Animation playing counter: {0}, address: 0x{1:X}, nameAddress: 0x{2:X}", amount, temp_debugging.ToInt64(), name_address.ToInt64()))); AnimationEvent?.Invoke(this, new StringArg(name)); } } ptr += 0x10; } First_Check = false; } }