lovalter Posted September 9, 2024 Posted September 9, 2024 Would it be possible to add more color options? Maybe an rgb picker?
segaegae Posted September 9, 2024 Posted September 9, 2024 (edited) 13 hours ago, nopse0 said: Can you post the log "C:\users\<your name>\Documents\My Games\Skyrim Special Edition\SKSE\SlaveTatsNG.log" ? It prints out some information about the game version, and DLL's it finds, and what addresses it uses. My idea to find out the addresses (never did this though, don't know if this is feasible), would be that you have both, a supported version and vr, installed. First look in one of the supported versions, what's at the known address offsets (hex dump bytes and/or dissassembly) and try to spot a significant byte sequence of the function, and then try to find the same byte sequence in the vr version (I don't know if the in memory offsets are the same as the offsets in the DLL file, so I think the best would be to search the byte sequence in memory starting from the base address of the loaded DLL). And then, if you have found the byte sequence, you have to find out where the function actually starts (maybe one can see this in the disassembler, or perhaps, if you are lucky, and the same compiler and optimization options were used, the offset from the byte sequence to the start of the function is the same). You can set breakpoints with Visual Studio (perhaps in the function, where I add the offsets to the base address of the DLL to get the function addresses), but you have to fork a new thread to execute the code where you want to set the breakpoint (the Skyrim threads don't support catching breakpoint exceptions). For example I did this in the simple_add_tattoo function: fail_t simple_add_tattoo(RE::StaticFunctionTag*, RE::Actor* a_target, RE::BSFixedString a_section, RE::BSFixedString a_name, int a_color, bool a_last = true, bool a_silent = false, float a_alpha = 1.0f) { fail_t result = false; std::thread t1 { [&] { result = ng::simple_add_tattoo(a_target, a_section.c_str(), a_name.c_str(), a_color, a_last, a_silent, a_alpha); logger::info("result is {}", result); } }; t1.join(); return result; } Then you can set a breakpoint in the line with ng::simple_add_tattoo (or in any function called by it), and the visual studio debugger stops there. Or, on second thought, much easier, write a program which calls the NIOverride functions, we want the addresses of, surround it with the fork and join thread pattern from above, so that you can set breakpoints in it, and then switch to dissasembly, and single step the assembler instructions until you get into the skeevr.dll, note the address, note the offset to the dll base address, and, voilas, done. Edit: Forget it, we cannot call functions, we don't know the addresses of (that's the problem), only the Papyrus VM knows them, because SKEE registered them there) Edit: I tried a while to support the old override and overlay plugin interface, which is used in the VR skee version, and finally gave up. Because the variant class which is used in the old interface for passing in and returning different types of values doesn't contain virtual methods you could override, (and to make things worse, it even uses a global string table from SKEE), so you would have to use a variant class with exactly the same memory layout as the variant class from the skee sources. So the only chance is getting the addresses of the low level functions without the variant stuff. Maybe expired6978 can merge his changes he made in the master branch when he changed the override and overlay plugin interface to the new version into the vr branch, and release a new skeevr version. Whoa I didn't expect this to be such complicated. My thought was since we have the source and someone has already patched the skeevr.dll, we might have some easier ways and some references. As for SlaveTats.log, here it is [09:44:56:306] Hello World Test Version [09:44:56:306] SlaveTatsNG v0-1-0-0 [09:44:56:306] Game version : 1-4-15-1 [09:44:56:307] JContainers Plugin Name seems to be: JContainersVR Like others I cannot get the game to load up with this mod, and crash logs are nowhere to find. It is extremely unlikely expired6978 will do anything about racemenu vr. He didn't even do anything for SE, and that is why this mod exists: https://www.nexusmods.com/skyrimspecialedition/mods/70161 For vr this esl mod contains a similar patch for racemenu vr https://www.nexusmods.com/skyrimspecialedition/mods/106712?tab=posts Edited September 9, 2024 by segaegae
nopse0 Posted September 9, 2024 Author Posted September 9, 2024 (edited) 14 hours ago, segaegae said: Whoa I didn't expect this to be such complicated. My thought was since we have the source and someone has already patched the skeevr.dll, we might have some easier ways and some references. As for SlaveTats.log, here it is [09:44:56:306] Hello World Test Version [09:44:56:306] SlaveTatsNG v0-1-0-0 [09:44:56:306] Game version : 1-4-15-1 [09:44:56:307] JContainers Plugin Name seems to be: JContainersVR Like others I cannot get the game to load up with this mod, and crash logs are nowhere to find. It is extremely unlikely expired6978 will do anything about racemenu vr. He didn't even do anything for SE, and that is why this mod exists: https://www.nexusmods.com/skyrimspecialedition/mods/70161 For vr this esl mod contains a similar patch for racemenu vr https://www.nexusmods.com/skyrimspecialedition/mods/106712?tab=posts One idea I had is: Many plugins hook into the Skyrim code (Faster-HDT-SMP, SmoothCam, etc), by replacing methods in the virtual method table of Skyrim classes with their own hook functions. Why not do the same, and replace the function "IVirtualMachine::BindNativeMethod" with a hook function, which dumps what is bound into a file ? I think I will try this some time. Ps: Yes, we have the source, but we (me) cannot compile it (requires old visual studio version, old Windows SDK, old skse sources in a subfolder, etc.) Edited September 9, 2024 by nopse0
bruhfrman Posted September 14, 2024 Posted September 14, 2024 (edited) Hey I have a major bug in the VR version. When I have this mod enabled, my SKSE won't launch my Skyrim, so it just says Skyrim is running on Steam but Skyrim actually doesn't launch. Fyi, I am also using some SlaveTats mods like FadeTattoos and RapeTattoos. Edit: I just saw others ar having the same bug, please let me know when/if this is fixed or if you need any info from me. Edited September 14, 2024 by bruhfrman
nopse0 Posted September 15, 2024 Author Posted September 15, 2024 On 9/14/2024 at 6:56 PM, bruhfrman said: Hey I have a major bug in the VR version. When I have this mod enabled, my SKSE won't launch my Skyrim, so it just says Skyrim is running on Steam but Skyrim actually doesn't launch. Fyi, I am also using some SlaveTats mods like FadeTattoos and RapeTattoos. Edit: I just saw others ar having the same bug, please let me know when/if this is fixed or if you need any info from me. Good news for VR users. What I mentioned before works, I can hook into the Papyrus VM RegisterFunction calls, and dump the adresses of the native fuctions when they are registered. Output looks like this: [20:49:18:125] [vm_hook] calling bind_native_function [20:49:18:125] [vm_hook] object: NiOverride, name: HasNodeOverride, callback: 140705203484032 [20:49:18:125] [vm_hook] calling bind_native_function [20:49:18:125] [vm_hook] object: NiOverride, name: AddNodeOverrideFloat, callback: 140705203632656 [20:49:18:125] [vm_hook] calling bind_native_function [20:49:18:125] [vm_hook] object: NiOverride, name: AddNodeOverrideInt, callback: 140705203633264 [20:49:18:125] [vm_hook] calling bind_native_function [20:49:18:125] [vm_hook] object: NiOverride, name: AddNodeOverrideBool, callback: 140705203633776 When I also dump the base addresses of the loaded DLL's, I can calculate the offsets. Btw: This are the addresses of the functions the VM calls, so probably some unpacking/packing of the Papyrus datatypes is needed (I think representation of Bools is different in C++ and Papyrus). But basically, it should be possible with that to get something working on VR. 1
bruhfrman Posted September 15, 2024 Posted September 15, 2024 14 minutes ago, nopse0 said: Good news for VR users. What I mentioned before works, I can hook into the Papyrus VM RegisterFunction calls, and dump the adresses of the native fuctions when they are registered. Output looks like this: [20:49:18:125] [vm_hook] calling bind_native_function [20:49:18:125] [vm_hook] object: NiOverride, name: HasNodeOverride, callback: 140705203484032 [20:49:18:125] [vm_hook] calling bind_native_function [20:49:18:125] [vm_hook] object: NiOverride, name: AddNodeOverrideFloat, callback: 140705203632656 [20:49:18:125] [vm_hook] calling bind_native_function [20:49:18:125] [vm_hook] object: NiOverride, name: AddNodeOverrideInt, callback: 140705203633264 [20:49:18:125] [vm_hook] calling bind_native_function [20:49:18:125] [vm_hook] object: NiOverride, name: AddNodeOverrideBool, callback: 140705203633776 When I also dump the base addresses of the loaded DLL's, I can calculate the offsets. Btw: This are the addresses of the functions the VM calls, so probably some unpacking/packing of the Papyrus datatypes is needed (I think representation of Bools is different in C++ and Papyrus). But basically, it should be possible with that to get something working on VR. I don't really know any of the technical talk, but when you release a new version you think works with VR I'm willing to try on a new game. I just have one question, can I use NG on an existing save if I was using the non-NG SlaveTats before?
nopse0 Posted September 15, 2024 Author Posted September 15, 2024 21 minutes ago, bruhfrman said: I don't really know any of the technical talk, but when you release a new version you think works with VR I'm willing to try on a new game. I just have one question, can I use NG on an existing save if I was using the non-NG SlaveTats before? Yes, you can, and vice versa, uses the same JContainer data structures as the original SlaveTats. When I am ready, one VR user must run the modified SlaveTatsNG (with enabled native function registration dumping) on VR, and send me the SlaveTatsNG.log. And you have to rename SlaveTatsNG.dll to _SlaveTatsNG.dll, because SKSE loads the plugins in alphabetical order, and my Hook must be installed before NiOverride registers its native functions.
nopse0 Posted September 15, 2024 Author Posted September 15, 2024 Uploaded a VR test version, which dumps the NIOverride native function addresses to a log file. Run it on VR, and send me the log file "C:\users\<your name>\Documents\My Games\Skyrim Special Edition\SKSE\SlaveTatsNG.log". Then I can implement a VR version. Tested it with 1.5.97, if I calculate the offsets with the dumped addresses, I get exactly the same offsets as in ponzypyramid's address tables, e.g. AddNodeOverrideFloat, callback: 140705230411648 GetModuleHandleA('skee64.dll') = 140705229635584 140705230411648 - 140705229635584 = 776064 = 0xbd780 (same offset as in address table from ponzypyramid)
bruhfrman Posted September 15, 2024 Posted September 15, 2024 8 minutes ago, nopse0 said: Uploaded a VR test version, which dumps the NIOverride native function addresses to a log file. Run it on VR, and send me the log file "C:\users\<your name>\Documents\My Games\Skyrim Special Edition\SKSE\SlaveTatsNG.log". Then I can implement a VR version. Tested it with 1.5.97, if I calculate the offsets with the dumped addresses, I get exactly the same offsets as in ponzypyramid's address tables, e.g. AddNodeOverrideFloat, callback: 140705230411648 GetModuleHandleA('skee64.dll') = 140705229635584 140705230411648 - 140705229635584 = 776064 = 0xbd780 (same offset as in address table from ponzypyramid) Where is the new test version, I don't see it on the mod page
nopse0 Posted September 15, 2024 Author Posted September 15, 2024 5 minutes ago, bruhfrman said: Where is the new test version, I don't see it on the mod page Now uploaded, took a bit
bruhfrman Posted September 15, 2024 Posted September 15, 2024 43 minutes ago, nopse0 said: Uploaded a VR test version, which dumps the NIOverride native function addresses to a log file. Run it on VR, and send me the log file "C:\users\<your name>\Documents\My Games\Skyrim Special Edition\SKSE\SlaveTatsNG.log". Then I can implement a VR version. Tested it with 1.5.97, if I calculate the offsets with the dumped addresses, I get exactly the same offsets as in ponzypyramid's address tables, e.g. AddNodeOverrideFloat, callback: 140705230411648 GetModuleHandleA('skee64.dll') = 140705229635584 140705230411648 - 140705229635584 = 776064 = 0xbd780 (same offset as in address table from ponzypyramid) This is all I got, but I had no MCM menu. [19:52:06:145] Hello World Test Version [19:52:06:145] SlaveTatsNG v0-1-0-0 [19:52:06:145] Game version : 1-4-15-1 [19:52:06:281] JContainers Plugin Name seems to be: JContainersVR
bruhfrman Posted September 15, 2024 Posted September 15, 2024 2 minutes ago, bruhfrman said: This is all I got, but I had no MCM menu. [19:52:06:145] Hello World Test Version [19:52:06:145] SlaveTatsNG v0-1-0-0 [19:52:06:145] Game version : 1-4-15-1 [19:52:06:281] JContainers Plugin Name seems to be: JContainersVR I also got this error in Vortex:
nopse0 Posted September 15, 2024 Author Posted September 15, 2024 4 minutes ago, bruhfrman said: I also got this error in Vortex: I had removed the output "Hello World Test Version", so I guess you have both installed, the old version ("SlaveTatsNG.dll") and the new version ("_SlaveTatsNG.dll", starting with a "_"). Remove the old version, you cannot have both (and it doesn't work anyway). I only included the .dll and nothing else, because more then dumping the addresses into the log file won't work anyway. Can you try again ? (with the old SlaveTatsNG removed)
bruhfrman Posted September 15, 2024 Posted September 15, 2024 5 minutes ago, nopse0 said: I had removed the output "Hello World Test Version", so I guess you have both installed, the old version ("SlaveTatsNG.dll") and the new version ("_SlaveTatsNG.dll", starting with a "_"). Remove the old version, you cannot have both (and it doesn't work anyway). I only included the .dll and nothing else, because more then dumping the addresses into the log file won't work anyway. Can you try again ? (with the old SlaveTatsNG removed) Oh yes I didn't realise it was the older one, I just removed the SlaveTatsNG.log and will try again now.
bruhfrman Posted September 15, 2024 Posted September 15, 2024 (edited) 46 minutes ago, nopse0 said: I had removed the output "Hello World Test Version", so I guess you have both installed, the old version ("SlaveTatsNG.dll") and the new version ("_SlaveTatsNG.dll", starting with a "_"). Remove the old version, you cannot have both (and it doesn't work anyway). I only included the .dll and nothing else, because more then dumping the addresses into the log file won't work anyway. Can you try again ? (with the old SlaveTatsNG removed) Hey I'm not sure if I'm doing somthing wrong but I have just the "SlaveTATSNG-vr-dump-addresses" installed and no log file is being created. Do I need to have the older slavetats (non-ng) installed? (The game does launch however but I see nothing in MCM) Edited September 16, 2024 by bruhfrman
DeepBlueFrog Posted September 16, 2024 Posted September 16, 2024 About the comment regarding Mod Events.. there is a small addon to Slade Tats that was developed specifically for Hormones - SlaveTats Event Bridge It just adds some mod events to listen to and translate to the Slave Tats API. Would that work out of the bod or does it need its own translation to the native functions?
nopse0 Posted September 16, 2024 Author Posted September 16, 2024 4 hours ago, DeepBlueFrog said: About the comment regarding Mod Events.. there is a small addon to Slade Tats that was developed specifically for Hormones - SlaveTats Event Bridge It just adds some mod events to listen to and translate to the Slave Tats API. Would that work out of the bod or does it need its own translation to the native functions? It should work out of the box, the events bridge just calls the normal SlaveTats functions, "SlaveTats.simple_add_tattoo" etc., it has nothing to do with the SlaveTats mod events (which are named "SlaveTats-added" and "SlaveTats-removed"). Maybe it's as bit inefficient, because if you have SlaveTatsNG installed, "SlaveTats.simple_add_tattoo" is just a dummy function, which calls "SlaveTatsNG.simple_add_tattoo", which in turn is a Global Native function, so you could directly call "SlaveTatsNG.simple_add_tattoo" and have the same effect. But, of course, I wouldn't change this, because of compatibility reasons, the time you would win by avoiding this indirection is minimal.
nopse0 Posted September 16, 2024 Author Posted September 16, 2024 (edited) 6 hours ago, bruhfrman said: Hey I'm not sure if I'm doing somthing wrong but I have just the "SlaveTATSNG-vr-dump-addresses" installed and no log file is being created. Do I need to have the older slavetats (non-ng) installed? (The game does launch however but I see nothing in MCM) First of all, if the _SlaveTatsNG.dll is loaded and the game doesn't crash, is a good sign (previously, I did a "GetModuleHandleA(skee64.dll)" on VR instead of "GetModuleHandleA(skeevr.dll)" to get the base address, so the base address was NULL and the program crashed). The log file is created in the standard log directory of SKSE, on SE/AE thats "My Games/Skyrim Special Edition", maybe the folder name is different on VR, perhaps "My Games/Skyrim VR" ? Do you mean, you have no SlaveTats MCM, or you have a SlaveTats MCM, but it shows no tattoos ? If no scripts/esp are installed, then there is no MCM; and if you have a MCM, but it shows no tattoos, then the SlaveTatsNG native functions don't work on VR. I know that the NiOverride function addresses are wrong on VR (that's why I want the log file with the dumped addresses), but this shouldn't have a influence on what is displayed in the MCM (that's pure JContainers stuff, nothing with NiOverride), so maybe something else is going wrong on VR, definitely need the log file. Edited September 16, 2024 by nopse0
bruhfrman Posted September 16, 2024 Posted September 16, 2024 9 hours ago, nopse0 said: First of all, if the _SlaveTatsNG.dll is loaded and the game doesn't crash, is a good sign (previously, I did a "GetModuleHandleA(skee64.dll)" on VR instead of "GetModuleHandleA(skeevr.dll)" to get the base address, so the base address was NULL and the program crashed). The log file is created in the standard log directory of SKSE, on SE/AE thats "My Games/Skyrim Special Edition", maybe the folder name is different on VR, perhaps "My Games/Skyrim VR" ? Do you mean, you have no SlaveTats MCM, or you have a SlaveTats MCM, but it shows no tattoos ? If no scripts/esp are installed, then there is no MCM; and if you have a MCM, but it shows no tattoos, then the SlaveTatsNG native functions don't work on VR. I know that the NiOverride function addresses are wrong on VR (that's why I want the log file with the dumped addresses), but this shouldn't have a influence on what is displayed in the MCM (that's pure JContainers stuff, nothing with NiOverride), so maybe something else is going wrong on VR, definitely need the log file. Game launches with no crash, but there is no log file being created, I checked it thoroughly. There is no SlaveTats MCM at all either. Not sure could also maybe be a problem with my setup. Will need a 2nd VR user to confirm.
nopse0 Posted September 16, 2024 Author Posted September 16, 2024 1 hour ago, bruhfrman said: Game launches with no crash, but there is no log file being created, I checked it thoroughly. There is no SlaveTats MCM at all either. Not sure could also maybe be a problem with my setup. Will need a 2nd VR user to confirm. Thanks! Btw., which JContainers version are you using, the newest JContainersVR 4.2.11 from Nexus ? I find it strange that in your first log, the output stopped after the line "JContainers Plugin Name seems to be: JContainersVR", normally it should have been tried to load the JContainer functions after that with a lot of output
bruhfrman Posted September 16, 2024 Posted September 16, 2024 2 hours ago, nopse0 said: Thanks! Btw., which JContainers version are you using, the newest JContainersVR 4.2.11 from Nexus ? I find it strange that in your first log, the output stopped after the line "JContainers Plugin Name seems to be: JContainersVR", normally it should have been tried to load the JContainer functions after that with a lot of output Yes I'm using the nexus one.
kamithemoon Posted September 16, 2024 Posted September 16, 2024 (edited) Also on VR. I tried the VR test version and this was my output: [16:15:38:065] Hello World Test Version [16:15:38:065] SlaveTatsNG v0-1-0-0 [16:15:38:065] Game version : 1-4-15-1 [16:15:39:382] JContainers Plugin Name seems to be: JContainersVR I have an MCM and was able to add tats normally but there was no further logging generated. @bruhfrman, if it helps any, SkyUI VR is loose files but MCM Helper and Menu Maid 2 can be either bsa or loose. I made the mistake of downloading the later 2 mods as bsa so SkyUI VR's scripts were not being overwritten as they were supposed to be which caused a bug I had to deal with for several years before I figured it out. This might help your MCM woes. Edited September 16, 2024 by kamithemoon
kamithemoon Posted September 16, 2024 Posted September 16, 2024 (edited) Found something maybe relevant: The MO2 is reporting that the VR DLL is failing to load due to a dependency DLL not being present. However, if I activate base SlaveTatsNG then the game won't load. I can run just the _SlaveTatsNG.dll and it will provide the short log above, so it's doing something, but that's it. Edited September 16, 2024 by kamithemoon
nopse0 Posted September 17, 2024 Author Posted September 17, 2024 18 hours ago, kamithemoon said: The MO2 is reporting that the VR DLL is failing to load due to a dependency DLL not being present. Another VR iteration: I saw that the Debug build I uploaded had a dependency on 'ucrtbased.dll'. Maybe this is part of the Windows SDK and not present on all Windows systems (and the missing dependency SKSE complains about). I built a release version, which is dependent on: KERNEL32.dll MSVCP140.dll MSVCP140_ATOMIC_WAIT.dll VCRUNTIME140_1.dll VCRUNTIME140.dll api-ms-win-crt-heap-l1-1-0.dll api-ms-win-crt-runtime-l1-1-0.dll api-ms-win-crt-math-l1-1-0.dll api-ms-win-crt-string-l1-1-0.dll api-ms-win-crt-stdio-l1-1-0.dll api-ms-win-crt-multibyte-l1-1-0.dll api-ms-win-crt-convert-l1-1-0.dll api-ms-win-crt-filesystem-l1-1-0.dll api-ms-win-crt-locale-l1-1-0.dll api-ms-win-crt-time-l1-1-0.dll ole32.dll VERSION.dll USER32.dll SHELL32.dll I think this is all pretty normal Windows stuff, except MSVCP and VCRUNTIME which is Visual Studio, but since you can run other plugins, you probably have a VC redistributable. One remark: I renamed the dll to "_SlaveTatsNG.dll", so that it is the first SKSE plugin which is loaded (otherwise my hook isn't active when the other plugins are loaded and register their native functions). Have only this in your SKSE/plugins folder, and remove the old SlaveTatsNG.dll and SlaveTatsNG.pdb.
kamithemoon Posted September 17, 2024 Posted September 17, 2024 (edited) 29 minutes ago, nopse0 said: Another VR iteration: I saw that the Debug build I uploaded had a dependency on 'ucrtbased.dll'. Maybe this is part of the Windows SDK and not present on all Windows systems (and the missing dependency SKSE complains about). I built a release version, which is dependent on: KERNEL32.dll MSVCP140.dll MSVCP140_ATOMIC_WAIT.dll VCRUNTIME140_1.dll VCRUNTIME140.dll api-ms-win-crt-heap-l1-1-0.dll api-ms-win-crt-runtime-l1-1-0.dll api-ms-win-crt-math-l1-1-0.dll api-ms-win-crt-string-l1-1-0.dll api-ms-win-crt-stdio-l1-1-0.dll api-ms-win-crt-multibyte-l1-1-0.dll api-ms-win-crt-convert-l1-1-0.dll api-ms-win-crt-filesystem-l1-1-0.dll api-ms-win-crt-locale-l1-1-0.dll api-ms-win-crt-time-l1-1-0.dll ole32.dll VERSION.dll USER32.dll SHELL32.dll I think this is all pretty normal Windows stuff, except MSVCP and VCRUNTIME which is Visual Studio, but since you can run other plugins, you probably have a VC redistributable. I can say though that MO2 no longer reports a missing .dll requirement. One remark: I renamed the dll to "_SlaveTatsNG.dll", so that it is the first SKSE plugin which is loaded (otherwise my hook isn't active when the other plugins are loaded and register their native functions). Have only this in your SKSE/plugins folder, and remove the old SlaveTatsNG.dll and SlaveTatsNG.pdb. Following your instructions and deleting the original .dll and pdb in favor of the new .dll from the newest VR release causes it to not load the game anymore, same as it did previously. However, I may have committed a noob mistake... It doesn't appear to be mentioned on your LL page but your Github link lists a number of requirements that I was not aware of. Particularly, CMake being added to PATH and Vcpkg being added to Vcpkg_root. I honestly have no idea what any of that means or how to do it =P. I don't even know if I have Powershell or not, though I think that comes built in with Win 11. Edited September 17, 2024 by kamithemoon
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now