Register for your free account! | Forgot your password?

Go Back   elitepvpers > MMORPGs > Nostale
You last visited: Today at 11:51

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



Question on how to get inventory list

Discussion on Question on how to get inventory list within the Nostale forum part of the MMORPGs category.

Reply
 
Old   #1
 
elite*gold: 0
Join Date: Oct 2024
Posts: 10
Received Thanks: 0
Question on how to get inventory list

Hi there, i was always interested in how to develop software, this summer i said to myself "why not?" and i started to study a bit of c++.
So the problem is, i'm playing nostale right now so i tought i could start with a bot for nostale to learn it but it is harder than i expected.
I started with simple security options, i got an open source packet logger and developed my own ui with qt, after some time the security worked just fine so i started with something more serious, how to get a list of the items in my inventory. And here is the problem: i can't get it to work. I tried to scan with cheat engine for the current amount of an item, dropped a part of it and scanned for the next value to find a single result, right clicked it and clicked on "find out what access this address", than i had four results with increased access with open inventory and no access with closed inventory. I click on the first result use the address found in "the value of the pointer needed to find this address is XXXXXX" to dissect the data structure. what i find is something like this
Code:
0000 - 4 Bytes (Hex)     68FAADC : FFFF00D3            
0004 - 4 Bytes           68FAAE0 : 3                   
0008 - 4 Bytes           68FAAE4 : 0                   
000C - 4 Bytes           68FAAE8 : 0                   
0010 - 4 Bytes (Hex)     68FAAEC : 000F0000            
0014 - 4 Bytes           68FAAF0 : 1                   
0018 - 4 Bytes           68FAAF4 : 0                   
001C - 4 Bytes           68FAAF8 : 0                   
0020 - 4 Bytes           68FAAFC : 0                   
0024 - 4 Bytes           68FAB00 : 0                   
0028 - 4 Bytes           68FAB04 : 0                   
002C - 4 Bytes           68FAB08 : 0                   
0030 - 4 Bytes           68FAB0C : 0                   
0034 - 4 Bytes           68FAB10 : 0                   
0038 - Pointer           68FAB14 : P->068F8590         
003C - 4 Bytes           68FAB18 : 0                   
0040 - 4 Bytes           68FAB1C : 0                   
0044 - Pointer           68FAB20 : P->0F932450         
0048 - 4 Bytes (Hex)     68FAB24 : FFFF03F4            
004C - 4 Bytes           68FAB28 : 1                   
0050 - 4 Bytes           68FAB2C : 0                   
0054 - 4 Bytes           68FAB30 : 0                   
0058 - 4 Bytes           68FAB34 : 1                   
005C - 4 Bytes           68FAB38 : 999                 
0060 - 4 Bytes           68FAB3C : 0                   
0064 - 4 Bytes           68FAB40 : 0                   
0068 - 4 Bytes           68FAB44 : 0                   
006C - 4 Bytes           68FAB48 : 0                   
0070 - 4 Bytes           68FAB4C : 0                   
0074 - 4 Bytes           68FAB50 : 0                   
0078 - 4 Bytes           68FAB54 : 0                   
007C - 4 Bytes           68FAB58 : 0                   
0080 - Pointer           68FAB5C : P->068F8590         
0084 - 4 Bytes           68FAB60 : 0                   
0088 - 4 Bytes           68FAB64 : 0                   
008C - Pointer           68FAB68 : P->0F931690         
0090 - 4 Bytes (Hex)     68FAB6C : FFFF03EA            
0094 - 4 Bytes           68FAB70 : 1                   
0098 - 4 Bytes           68FAB74 : 0                   
009C - 4 Bytes           68FAB78 : 0                   
00A0 - Pointer           68FAB7C : P->00010001         
00A4 - 4 Bytes           68FAB80 : 5                   
00A8 - 4 Bytes           68FAB84 : 0                   
00AC - 4 Bytes           68FAB88 : 0                   
00B0 - 4 Bytes           68FAB8C : 0                   
00B4 - 4 Bytes           68FAB90 : 0                   
00B8 - 4 Bytes           68FAB94 : 0                   
00BC - 4 Bytes           68FAB98 : 0                   
00C0 - 4 Bytes           68FAB9C : 0                   
00C4 - 4 Bytes           68FABA0 : 0                   
00C8 - Pointer           68FABA4 : P->068F8590         
00CC - 4 Bytes           68FABA8 : 0                   
00D0 - 4 Bytes           68FABAC : 0                   
00D4 - Pointer           68FABB0 : P->0F90AC90         
00D8 - 4 Bytes (Hex)     68FABB4 : FFFF04DE            
00DC - 4 Bytes           68FABB8 : 1                   
00E0 - 4 Bytes           68FABBC : 0                   
00E4 - 4 Bytes           68FABC0 : 0                   
00E8 - Pointer           68FABC4 : P->00020001         
00EC - 4 Bytes           68FABC8 : 27                  
00F0 - 4 Bytes           68FABCC : 0                   
00F4 - 4 Bytes           68FABD0 : 0                   
00F8 - 4 Bytes           68FABD4 : 0                   
00FC - 4 Bytes           68FABD8 : 0                   
0100 - 4 Bytes           68FABDC : 0
There are item id's and current amount, i'm doing it right? do you have suggestions on how to go about it from now?
If you have some time to waste on this i would be glad, and if you can explain how to go about it like you would explain it to a monkey. Thanks.
SalvoM is offline  
Old 11/01/2024, 10:07   #2
 
elite*gold: 0
Join Date: Oct 2018
Posts: 257
Received Thanks: 207
Cannot you use inv/ivn packets instead?
Apourtartt is offline  
Old 11/01/2024, 11:06   #3
 
elite*gold: 0
Join Date: Oct 2024
Posts: 10
Received Thanks: 0
First, thank you very much for your answer. I tought about that but i get the inv packet only when i start the game so if i inject the dll after i can't access the inv packet anymore.
I checked the logs and i see only the "npinfo 0" packet sent before all the info about the character. I need to send that again when i refresh the item list in the ui? Isn't it risky? And when the bot will use an item (potions for example)do you think it's "safe" to send the packet or do you suggest to use the in game function if possible? Sorry for asking so many questions, i'm just very new to this.
SalvoM is offline  
Old 11/01/2024, 11:37   #4
 
Hatz~'s Avatar
 
elite*gold: 0
Join Date: May 2020
Posts: 369
Received Thanks: 448
As long as you craft the packet correctly it should be safe. Calling a game function for using items will only craft the packet for you and send it to the server.
Hatz~ is offline  
Thanks
1 User
Old 11/01/2024, 14:59   #5
 
elite*gold: 0
Join Date: Oct 2018
Posts: 257
Received Thanks: 207
Quote:
Originally Posted by SalvoM View Post
First, thank you very much for your answer. I tought about that but i get the inv packet only when i start the game so if i inject the dll after i can't access the inv packet anymore.
I checked the logs and i see only the "npinfo 0" packet sent before all the info about the character. I need to send that again when i refresh the item list in the ui? Isn't it risky? And when the bot will use an item (potions for example)do you think it's "safe" to send the packet or do you suggest to use the in game function if possible? Sorry for asking so many questions, i'm just very new to this.
I would suggest to customize EWSF.EWS in order to auto-inject your software and continue full packet-based.
If being memory based is a requirement (which I wouldn't recommend, because of the complexity and the maintenance it required), please make it clear
Apourtartt is offline  
Thanks
1 User
Old 11/01/2024, 15:07   #6
 
elite*gold: 0
Join Date: Oct 2024
Posts: 10
Received Thanks: 0
Quote:
Originally Posted by Hatz~ View Post
As long as you craft the packet correctly it should be safe. Calling a game function for using items will only craft the packet for you and send it to the server.
So, i tried to use some items with the packet logger opened and if i got it right it is "u_i 1 playerid inventorytype PositionInInventory 0 0"?
I can find the playerID scanning the memory for the value i find in the cond packet, the inventory type for basic items is 0 for equipment, 1 for potions and the like and 2 for snacks. For every item i use the last two values are 0 0, i assume i can go with those for almost every item?
I'm still stuck on how to get the item list.

Quote:
Originally Posted by Apourtartt View Post
I would suggest to customize EWSF.EWS in order to auto-inject your software and continue full packet-based.
If being memory based is a requirement (which I wouldn't recommend, because of the complexity and the maintenance it required), please make it clear
I'm sorry, like i said i'm very new to this, can you elaborate please?
From what i read in this forum the safest option for target, attack and walk is to use the in-game functions, am i wrong?
SalvoM is offline  
Old 11/01/2024, 15:17   #7
 
elite*gold: 0
Join Date: Oct 2024
Posts: 10
Received Thanks: 0
Quote:
Originally Posted by Hatz~ View Post
As long as you craft the packet correctly it should be safe. Calling a game function for using items will only craft the packet for you and send it to the server.
So, i tried to use some items with the packet logger opened and if i got it right it is "u_i 1 playerid inventorytype PositionInInventory 0 0"?
I can find the playerID scanning the memory for the value i find in the cond packet, the inventory type for basic items is 0 for equipment, 1 for potions and the like and 2 for snacks. For every item i use the last two values are 0 0, i assume i can go with those for almost every item?
I'm still stuck on how to get the item list.

Quote:
Originally Posted by Apourtartt View Post
I would suggest to customize EWSF.EWS in order to auto-inject your software and continue full packet-based.
If being memory based is a requirement (which I wouldn't recommend, because of the complexity and the maintenance it required), please make it clear
I'm sorry, like i said i'm very new to this, can you elaborate please?
From what i read in this forum the safest option for target, attack and walk is to use the in-game functions, am i wrong?
SalvoM is offline  
Old 11/01/2024, 15:27   #8
 
elite*gold: 0
Join Date: Oct 2018
Posts: 257
Received Thanks: 207
Quote:
Originally Posted by SalvoM View Post
I'm sorry, like i said i'm very new to this, can you elaborate please?
From what i read in this forum the safest option for target, attack and walk is to use the in-game functions, am i wrong?
EWSF.EWS is a file you have in your Nostale directory. In reality it is a .dll file that exports two functions: ShowNostaleSplash and FreeNostaleSplash.
What you can do is to make your software to export those functions and consider ShowNostaleSplash as your current main function.
That way, you make sure your software is ready even before the player connects, and therefore, be able to get the inv packets.
Here is an example:

I wouldn't say one is safer than the other, but it is indeed easier to screw up by using packets, because game functions (not all, but some of them) have some safeguards.
If your packet-based software is able to make you ban, so will your memory-based software, and the other way around.
Apourtartt is offline  
Thanks
1 User
Old 11/01/2024, 16:56   #9
 
elite*gold: 0
Join Date: Oct 2024
Posts: 10
Received Thanks: 0
Quote:
Originally Posted by Apourtartt View Post
EWSF.EWS is a file you have in your Nostale directory. In reality it is a .dll file that exports two functions: ShowNostaleSplash and FreeNostaleSplash.
What you can do is to make your software to export those functions and consider ShowNostaleSplash as your current main function.
That way, you make sure your software is ready even before the player connects, and therefore, be able to get the inv packets.
Here is an example:

I wouldn't say one is safer than the other, but it is indeed easier to screw up by using packets, because game functions (not all, but some of them) have some safeguards.
If your packet-based software is able to make you ban, so will your memory-based software, and the other way around.
I tought i had seen something similar when i started this bot to learn c++ and searched some open source projects for reference.
Turns out it is an unfinished project of yours, if i got it right the final result would be something similar to that.
Then to summarize it would be like this(?):

for packet-based bot
pros:
Easier to develope.
Way less maintenance needed because there is no need to update patterns and pointers.
No need for asm code.
cons:
Need to start the bot before the game?
Higher chance to get a ban if i mess up the code and send the wrong packet.
longer code.


for memory-based bot
pros:
Less chance to get a ban if i mess up the code because probably the game will just crash?
Can start the bot whenever.
Less code.
cons:
Harder to develope.
Need to update pointers and patterns after some game updates.
Need asm code.

I think i will go for the memory-based bot for now, after all i'm trying to develope it more to learn to code than to use the bot itself.
Still, thank you very much for your help.
SalvoM is offline  
Old 11/01/2024, 22:45   #10
 
elite*gold: 0
Join Date: Dec 2011
Posts: 43
Received Thanks: 19
Maybe this is what you are looking for:

TNTCharacterInventoryInfoWidget: F0 FB ?? ?? 90 49 ?? ?? D0 69 ?? ?? 60 90 ?? ??

+ 021C: TNTItemList
+ 0220: TNTItemList
+ 0224: TNTItemList
+ 0248: TNTCardInventoryInfoWidget
+ 024C: TNTCostumeInventoryInfoWidget

For example read item name:
HTML Code:
#include <Windows.h>
#include <iostream>
#include <iomanip>
#include <cstdint>
#include <vector>

int main()
{
	HWND hwnd = FindWindow("TNosTaleMainF", "NosTale");
	DWORD pid;
	GetWindowThreadProcessId(hwnd, &pid);
	HANDLE handle;
	handle = OpenProcess(PROCESS_ALL_ACCESS, false, pid);

	for (uint32_t i = 0; i < 0x4 * 20; i += 0x4)
	{
		uint32_t address = 0x00400000;

		// Pattern is : NostaleClientX.exe+4F9C50
		ReadProcessMemory(handle, (LPCVOID)(address + 0x004F9C50), &address, sizeof(address), NULL);
		//std::cout << "0x" << std::setw(8) << std::setfill('0') << std::hex << address << std::endl;

		ReadProcessMemory(handle, (LPCVOID)(address + 0x021C), &address, sizeof(address), NULL);
		//std::cout << "0x" << std::setw(8) << std::setfill('0') << std::hex << address << std::endl;

		ReadProcessMemory(handle, (LPCVOID)(address + 0x4), &address, sizeof(address), NULL);
		//std::cout << "0x" << std::setw(8) << std::setfill('0') << std::hex << address << std::endl;

		ReadProcessMemory(handle, (LPCVOID)(address + i), &address, sizeof(address), NULL);
		//std::cout << "0x" << std::setw(8) << std::setfill('0') << std::hex << address << std::endl;

		ReadProcessMemory(handle, (LPCVOID)(address + 0x0), &address, sizeof(address), NULL);
		//std::cout << "0x" << std::setw(8) << std::setfill('0') << std::hex << address << std::endl;

		ReadProcessMemory(handle, (LPCVOID)(address + 0xE0), &address, sizeof(address), NULL);
		//std::cout << "0x" << std::setw(8) << std::setfill('0') << std::hex << address << std::endl;

		ReadProcessMemory(handle, (LPCVOID)(address + 0x38), &address, sizeof(address), NULL);
		//std::cout << "0x" << std::setw(8) << std::setfill('0') << std::hex << address << std::endl;

		// Item Name (Ty ChatGPT)
		std::vector<char> buffer(256);
		ReadProcessMemory(handle, (LPCVOID)address, buffer.data(), buffer.size(), NULL);
		std::cout << buffer.data() << std::endl;
	}
}
JONNST4R is offline  
Thanks
1 User
Old 11/02/2024, 13:23   #11
 
elite*gold: 0
Join Date: Oct 2024
Posts: 10
Received Thanks: 0
Quote:
Originally Posted by JONNST4R View Post
Maybe this is what you are looking for:

TNTCharacterInventoryInfoWidget: F0 FB ?? ?? 90 49 ?? ?? D0 69 ?? ?? 60 90 ?? ??

+ 021C: TNTItemList
+ 0220: TNTItemList
+ 0224: TNTItemList
+ 0248: TNTCardInventoryInfoWidget
+ 024C: TNTCostumeInventoryInfoWidget

For example read item name:
HTML Code:
#include <Windows.h>
#include <iostream>
#include <iomanip>
#include <cstdint>
#include <vector>

int main()
{
	HWND hwnd = FindWindow("TNosTaleMainF", "NosTale");
	DWORD pid;
	GetWindowThreadProcessId(hwnd, &pid);
	HANDLE handle;
	handle = OpenProcess(PROCESS_ALL_ACCESS, false, pid);

	for (uint32_t i = 0; i < 0x4 * 20; i += 0x4)
	{
		uint32_t address = 0x00400000;

		// Pattern is : NostaleClientX.exe+4F9C50
		ReadProcessMemory(handle, (LPCVOID)(address + 0x004F9C50), &address, sizeof(address), NULL);
		//std::cout << "0x" << std::setw(8) << std::setfill('0') << std::hex << address << std::endl;

		ReadProcessMemory(handle, (LPCVOID)(address + 0x021C), &address, sizeof(address), NULL);
		//std::cout << "0x" << std::setw(8) << std::setfill('0') << std::hex << address << std::endl;

		ReadProcessMemory(handle, (LPCVOID)(address + 0x4), &address, sizeof(address), NULL);
		//std::cout << "0x" << std::setw(8) << std::setfill('0') << std::hex << address << std::endl;

		ReadProcessMemory(handle, (LPCVOID)(address + i), &address, sizeof(address), NULL);
		//std::cout << "0x" << std::setw(8) << std::setfill('0') << std::hex << address << std::endl;

		ReadProcessMemory(handle, (LPCVOID)(address + 0x0), &address, sizeof(address), NULL);
		//std::cout << "0x" << std::setw(8) << std::setfill('0') << std::hex << address << std::endl;

		ReadProcessMemory(handle, (LPCVOID)(address + 0xE0), &address, sizeof(address), NULL);
		//std::cout << "0x" << std::setw(8) << std::setfill('0') << std::hex << address << std::endl;

		ReadProcessMemory(handle, (LPCVOID)(address + 0x38), &address, sizeof(address), NULL);
		//std::cout << "0x" << std::setw(8) << std::setfill('0') << std::hex << address << std::endl;

		// Item Name (Ty ChatGPT)
		std::vector<char> buffer(256);
		ReadProcessMemory(handle, (LPCVOID)address, buffer.data(), buffer.size(), NULL);
		std::cout << buffer.data() << std::endl;
	}
}
Ty very much, this is what i search for.
Can you explain to me how you got the pattern and the offsets or suggest some tutorial on how to do it? So i can learn and search by myself other patterns or pointers.
SalvoM is offline  
Old 11/02/2024, 19:41   #12
 
elite*gold: 0
Join Date: Dec 2011
Posts: 43
Received Thanks: 19
Hey,

this is a good starting point. The given structures are outdated but the pattern (memory signatures, or how you call it) still work. (this saves you hours)

Add the address that is in the value of the found address with the pattern to
"Dissect data/structures" play around with it and you understand.

If you use "find out what access this address" on the given pattern for SceneManager you almost find all the functions you need to write a bot.

Source:
JONNST4R is offline  
Thanks
1 User
Reply


Similar Threads Similar Threads
[LIST] WarRock Privat Server List! [LIST]
07/27/2013 - WarRock - 46 Replies
http://archiv.so/images/2013/03/01/bQaXx.png Hallo elitepvpers Community! Da es in letzter Zeit viele unnötige Threads, mit Fragen zu guten Privat Servern gab, möchte ich es Neulingen (Newbies) etwas erleichern! Und das ganze soll durch diese Liste an mir bekannten WarRock P-Servern geschehen. Sollten euch noch weitere Server bekannt sein, schreibt den Thread-Link & Namen als Kommentar, damit ich diesen Server eventueller Weise auch noch rein editieren kann.



All times are GMT +1. The time now is 11:52.


Powered by vBulletin®
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2025 elitepvpers All Rights Reserved.