private void ForceUpdate() { Debug_Message?.Invoke(this, new StringArg("ForceUpdate")); //set time to zero so the update loop is force to do a update prevUpdate = new DateTime(0); nextUpdate = new DateTime(0); }
public bool Init() { if (Game_Name == Game.Skyrim.Executable_Name) { timer_offsets = new int[] { 0xF10588, 0x88, 0x4, 0x100, 0x10, 0x98, 0x58, 0x0, 0x44 }; ptr_data = Inject_TESV(); } else if (Game_Name == Game.SkyrimSe.Executable_Name) { timer_offsets = new int[] { 0x01EC47C8, 0xD0, 0x8, 0x1B0, 0x20, 0x118, 0x98, 0x0, 0x44 }; ptr_data = Inject_SkyrimSE(); } else if (Game_Name == Game.SkyrimVr.Executable_Name) { timer_offsets = new int[] { 0x01F89668, 0xD0, 0x8, 0x1A8, 0x48, 0x0, 0x118, 0x98, 0x0, 0x44 }; ptr_data = Inject_SkyrimVR(); } if (ptr_data == IntPtr.Zero) { Warning_Message?.Invoke(this, new StringArg("No pointer was found!")); return(false);//return failure } Debug_Message?.Invoke(this, new StringArg(String.Format("Found data address: 0x{0:X}", ptr_data.ToInt64()))); IntPtr test1 = memory.ReadPointer(timer_offsets); Debug_Message?.Invoke(this, new StringArg(String.Format("Animation timer address is currenty: 0x{0:X}", test1.ToInt64()))); float test2 = memory.ReadFloat(test1); Debug_Message?.Invoke(this, new StringArg("animation timer is:" + test2)); Thread_Check_Events = new Thread(Check_Events) { IsBackground = true }; Thread_Check_Events.Start(); Thread_Check_Timer = new Thread(Check_Timer) { IsBackground = true }; Thread_Check_Timer.Start(); Thread_Check_Game_Running = new Thread(Check_Game_Running) { IsBackground = true }; Thread_Check_Game_Running.Start(); return(true);//return succes }
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 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; } }
private async void UpdateLoop() { double old_position = 0; double new_position = 0; double cur_position = 0; bool paused = false; while (!disposed) { Thread.Sleep(5); //if (!gameRunning) continue; //check if there are running events bool has_events = false; lock (running_events) { has_events = running_events.Count != 0; } if (!has_events) { old_position = 0; new_position = 0; await Set(0); await Set(0, 300); continue; } DateTime timeNow = DateTime.Now; if (!Game_Running) { if (!paused) { paused = true; double position = ((double)(timeNow - prevUpdate).TotalMilliseconds / (double)(nextUpdate - prevUpdate).TotalMilliseconds * (new_position - old_position)) + old_position; await Set(position, 100); //pause at current possition await Set(0); } continue; } if (paused) { paused = false; ForceUpdate(); } if (timeNow >= nextUpdate) { List <double> positions = new List <double>(); lock (running_events) { //update all events and find next update time foreach (Running_Event running_event in running_events) { running_event.Update(timeNow); } //remove events that are done for (int i = running_events.Count - 1; i >= 0; i--) { if (running_events[i].ended) { running_events.RemoveAt(i); EventListUpdated?.Invoke(this, EventArgs.Empty); } } //find earliest time at wich point we need to do a update again foreach (Running_Event running_event in running_events) { if (nextUpdate < running_event.nextTime) { prevUpdate = timeNow; nextUpdate = running_event.nextTime; } } //Find positions of all events at next update location foreach (Running_Event running_event in running_events) { positions.Add(running_event.GetPosition(nextUpdate) / 99.0d); } } if (positions.Count == 0) { //No events are plaing on this device so we can set it back to position 0 old_position = 0; new_position = 0; await Set(0, 1000); continue; } //avarage the positions to get final position double position = 0; foreach (double p in positions) { position += p; } new_position = Math.Min(position / positions.Count, 99d); old_position = cur_position; Debug_Message?.Invoke(this, new StringArg(String.Format("Current position:{0}, New position:{1}", cur_position, new_position))); //calculate duration to next point uint duration = (uint)(nextUpdate - timeNow).TotalMilliseconds; try { await Set(new_position, duration); }catch { } //We want to update it directly nextIntermediateUpdate = timeNow; } if (timeNow >= nextIntermediateUpdate) { nextIntermediateUpdate = timeNow + IntermediateUpdateInterval; double old_cur_position = cur_position; cur_position = ((double)(timeNow - prevUpdate).TotalMilliseconds / (double)(nextUpdate - prevUpdate).TotalMilliseconds * (new_position - old_position)) + old_position; if (Double.IsNaN(cur_position) || Double.IsInfinity(cur_position)) { cur_position = old_cur_position; } double test = Math.Abs(new_position - old_position) / (double)(nextUpdate - prevUpdate).TotalMilliseconds * 200; Debug_Message?.Invoke(this, new StringArg(String.Format("Intermediate Update Strength: {0} or {1}", cur_position, test))); try { //await Set(test); await Set(cur_position); } catch { } } } }