|
You last visited: Today at 18:48
Advertisement
[Clientless] Get skill name using skill id
Discussion on [Clientless] Get skill name using skill id within the Nostale forum part of the MMORPGs category.
06/16/2019, 01:56
|
#1
|
elite*gold: 0
Join Date: Jun 2019
Posts: 102
Received Thanks: 228
|
[Clientless] Get skill name using skill id
Everything is in the title, is it possible to get the skill name using it's id
I want to populate a collection with all the skills of the player (when ski packet is received, but i want to show the "real" name of the skill, i've unpacked NSlangData.NOS file, i've found a code_"language"_Skill file containing all the skill name/description but i can't find a way to "link" the skill id and the id in the code_Skill file, for example Hawk eye id in file is zts476e but id in packet is something like 8XX, so do i need to make the "link" between them myself or there is way to get the correct name directly ?
|
|
|
06/16/2019, 02:17
|
#2
|
elite*gold: 0
Join Date: Jun 2011
Posts: 126
Received Thanks: 99
|
|
|
|
06/16/2019, 03:06
|
#3
|
elite*gold: 50
Join Date: Jul 2014
Posts: 1,700
Received Thanks: 1,165
|
Quote:
Originally Posted by Roxeez
Everything is in the title, is it possible to get the skill name using it's id
I want to populate a collection with all the skills of the player (when ski packet is received, but i want to show the "real" name of the skill, i've unpacked NSlangData.NOS file, i've found a code_"language"_Skill file containing all the skill name/description but i can't find a way to "link" the skill id and the id in the code_Skill file, for example Hawk eye id in file is zts476e but id in packet is something like 8XX, so do i need to make the "link" between them myself or there is way to get the correct name directly ?
|
get the Skill id search it in the skill.dat get the zts for name and search it in the code_language_skill file and tada done.
or just import on startup all skills replace each zts by real name from the language file and done.
|
|
|
06/16/2019, 16:07
|
#4
|
elite*gold: 0
Join Date: Jul 2014
Posts: 283
Received Thanks: 317
|
NSgtdData.NOS -> Skill.dat
you can split by #===... (57 times the "=" sign) and ignore every line but the ones starting with "VNUM" and "NAME", notice there are tabulators (\t) in the beginning of each line and also it's the delimiter for values.
The ID from the packet is the VNUM, and the line under has got your desired zts_e value.
So you'll have to create a list of VNUM=>ztsID, preferably at the start of the clientless.
|
|
|
06/16/2019, 21:13
|
#5
|
elite*gold: 0
Join Date: Jun 2019
Posts: 102
Received Thanks: 228
|
Ok thanks, everything seems to work
- Decrypt NSgtdData.NOS then get skill id (VNUM) and skill name id(NAME) in Skill.dat
- Decrypt NSlangData.NOS get the string value from _code_"languageId"_Skill.txt
That's the c# decryptor class i've "made" based on OnexExplorer decryptor maybe someone will need it idk
Code:
/// <summary>
/// C# version of https://github.com/OnexTale/OnexExplorer/blob/master/Source/Decryptors/NosTextDatFileDecryptor.cpp
/// </summary>
public class NosTextDatFileDecryptor
{
private readonly byte[] CryptoArray = { 0x00, 0x20, 0x2D, 0x2E, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x0A, 0x00 };
public string Decrypt(byte[] bytes)
{
var decrypted = new StringBuilder();
int index = 0;
while (index < bytes.Length)
{
byte current = bytes[index];
index++;
if (current == 0xFF)
{
decrypted.Append(Convert.ToChar(0xD));
continue;
}
int validate = current & 0x7F;
if ((current & 0x80) != 0)
{
for (; validate > 0; validate -= 2)
{
if (index >= bytes.Length)
break;
current = bytes[index];
index++;
byte firstByte = CryptoArray[(current & 0xF0) >> 4];
decrypted.Append(Convert.ToChar(firstByte));
if (validate <= 1)
break;
byte secondByte = CryptoArray[current & 0xF];
if (secondByte == 0)
break;
decrypted.Append(Convert.ToChar(secondByte));
}
}
else
{
for (; validate > 0; --validate)
{
if (index >= bytes.Length)
break;
current = bytes[index];
index++;
decrypted.Append(Convert.ToChar((byte)(current ^ 0x33)));
}
}
}
return decrypted.ToString();
}
}
|
|
|
06/17/2019, 00:21
|
#6
|
elite*gold: 0
Join Date: Jan 2018
Posts: 44
Received Thanks: 69
|
Quote:
Originally Posted by Roxeez
Ok thanks, everything seems to work
- Decrypt NSgtdData.NOS then get skill id (VNUM) and skill name id(NAME) in Skill.dat
- Decrypt NSlangData.NOS get the string value from _code_"languageId"_Skill.txt
That's the c# decryptor class i've "made" based on OnexExplorer decryptor maybe someone will need it idk
Code:
/// <summary>
/// C# version of https://github.com/OnexTale/OnexExplorer/blob/master/Source/Decryptors/NosTextDatFileDecryptor.cpp
/// </summary>
public class NosTextDatFileDecryptor
{
private readonly byte[] CryptoArray = { 0x00, 0x20, 0x2D, 0x2E, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x0A, 0x00 };
public string Decrypt(byte[] bytes)
{
var decrypted = new StringBuilder();
int index = 0;
while (index < bytes.Length)
{
byte current = bytes[index];
index++;
if (current == 0xFF)
{
decrypted.Append(Convert.ToChar(0xD));
continue;
}
int validate = current & 0x7F;
if ((current & 0x80) != 0)
{
for (; validate > 0; validate -= 2)
{
if (index >= bytes.Length)
break;
current = bytes[index];
index++;
byte firstByte = CryptoArray[(current & 0xF0) >> 4];
decrypted.Append(Convert.ToChar(firstByte));
if (validate <= 1)
break;
byte secondByte = CryptoArray[current & 0xF];
if (secondByte == 0)
break;
decrypted.Append(Convert.ToChar(secondByte));
}
}
else
{
for (; validate > 0; --validate)
{
if (index >= bytes.Length)
break;
current = bytes[index];
index++;
decrypted.Append(Convert.ToChar((byte)(current ^ 0x33)));
}
}
}
return decrypted.ToString();
}
}
|
In case you want something more useable with not getting chopped of texts and having to handle everything on your own..
Code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
public class NFile
{
private string name { get; set; }
private int fileNumber { get; set; }
private int isDat { get; set; }
private byte[] data { get; set; }
public NFile(string _name, int _fileNumber, int _isDat, byte[] _data)
{
name = _name;
fileNumber = _fileNumber;
isDat = _isDat;
data = _data;
}
}
public static class NosTxtDecryptor
{
private static readonly byte[] cryptoArray = { 0x00, 0x20, 0x2D, 0x2E, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x0A, 0x00 };
private static byte[] decrypt(byte[] array)
{
List<byte> decryptedFile = new List<byte>();
int currindex = 0;
while (currindex < array.Length)
{
char currentByte = Convert.ToChar(array[currindex++]);
if (currentByte == 0xFF)
{
decryptedFile.Add(0xD);
continue;
}
int validate = currentByte & 0x7F;
if ((currentByte & 0x80) != 0)
{
for (; validate > 0; validate -= 2)
{
if (currindex >= array.Length)
{
break;
}
currentByte = Convert.ToChar(array[currindex++]);
decryptedFile.Add(cryptoArray[(currentByte & 0xF0) >> 4]);
if (validate <= 1)
{
break;
}
if (cryptoArray[currentByte & 0xF] == 0)
{
break;
}
decryptedFile.Add(cryptoArray[currentByte & 0xF]);
}
}
else
{
for (; validate > 0; --validate)
{
if (currindex >= array.Length)
{
break;
}
currentByte = Convert.ToChar(array[currindex++]);
decryptedFile.Add(Convert.ToByte(currentByte ^ 0x33));
}
}
}
return decryptedFile.ToArray();
}
public static List<NFile> GetNFiles(FileStream f)
{
List<NFile> retList = new List<NFile>();
f.Seek(0, SeekOrigin.Begin);
int fileAmount = f.readNextInt();
for (int i = 0; i < fileAmount; i++)
{
int fileNumber = f.readNextInt();
int stringNameSize = f.readNextInt();
string stringName = f.readString(stringNameSize);
int isDat = f.readNextInt();
int fileSize = f.readNextInt();
byte[] fileContent = f.readLength(fileSize);
retList.Add(new NFile(stringName, fileNumber, isDat, decrypt(fileContent)));
}
return retList;
}
private static int readNextInt(this FileStream fileSteam)
{
byte[] buffer = new byte[4];
fileSteam.Read(buffer, 0, 4);
return BitConverter.ToInt32(buffer, 0);
}
private static string readString(this FileStream fileStream, int count)
{
byte[] buffer = new byte[count];
fileStream.Read(buffer, 0, count);
return Encoding.Default.GetString(buffer);
}
private static byte[] readLength(this FileStream fileStream, int count)
{
byte[] buffer = new byte[count];
fileStream.Read(buffer, 0, count);
return buffer;
}
}
might not be the best way to rewrite everything but it's somewhat useable.
|
|
|
06/17/2019, 02:28
|
#7
|
elite*gold: 0
Join Date: Jun 2019
Posts: 102
Received Thanks: 228
|
Quote:
Originally Posted by AfterLife-
In case you want something more useable with not getting chopped of texts and having to handle everything on your own..
Code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
public class NFile
{
private string name { get; set; }
private int fileNumber { get; set; }
private int isDat { get; set; }
private byte[] data { get; set; }
public NFile(string _name, int _fileNumber, int _isDat, byte[] _data)
{
name = _name;
fileNumber = _fileNumber;
isDat = _isDat;
data = _data;
}
}
public static class NosTxtDecryptor
{
private static readonly byte[] cryptoArray = { 0x00, 0x20, 0x2D, 0x2E, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x0A, 0x00 };
private static byte[] decrypt(byte[] array)
{
List<byte> decryptedFile = new List<byte>();
int currindex = 0;
while (currindex < array.Length)
{
char currentByte = Convert.ToChar(array[currindex++]);
if (currentByte == 0xFF)
{
decryptedFile.Add(0xD);
continue;
}
int validate = currentByte & 0x7F;
if ((currentByte & 0x80) != 0)
{
for (; validate > 0; validate -= 2)
{
if (currindex >= array.Length)
{
break;
}
currentByte = Convert.ToChar(array[currindex++]);
decryptedFile.Add(cryptoArray[(currentByte & 0xF0) >> 4]);
if (validate <= 1)
{
break;
}
if (cryptoArray[currentByte & 0xF] == 0)
{
break;
}
decryptedFile.Add(cryptoArray[currentByte & 0xF]);
}
}
else
{
for (; validate > 0; --validate)
{
if (currindex >= array.Length)
{
break;
}
currentByte = Convert.ToChar(array[currindex++]);
decryptedFile.Add(Convert.ToByte(currentByte ^ 0x33));
}
}
}
return decryptedFile.ToArray();
}
public static List<NFile> GetNFiles(FileStream f)
{
List<NFile> retList = new List<NFile>();
f.Seek(0, SeekOrigin.Begin);
int fileAmount = f.readNextInt();
for (int i = 0; i < fileAmount; i++)
{
int fileNumber = f.readNextInt();
int stringNameSize = f.readNextInt();
string stringName = f.readString(stringNameSize);
int isDat = f.readNextInt();
int fileSize = f.readNextInt();
byte[] fileContent = f.readLength(fileSize);
retList.Add(new NFile(stringName, fileNumber, isDat, decrypt(fileContent)));
}
return retList;
}
private static int readNextInt(this FileStream fileSteam)
{
byte[] buffer = new byte[4];
fileSteam.Read(buffer, 0, 4);
return BitConverter.ToInt32(buffer, 0);
}
private static string readString(this FileStream fileStream, int count)
{
byte[] buffer = new byte[count];
fileStream.Read(buffer, 0, count);
return Encoding.Default.GetString(buffer);
}
private static byte[] readLength(this FileStream fileStream, int count)
{
byte[] buffer = new byte[count];
fileStream.Read(buffer, 0, count);
return buffer;
}
}
might not be the best way to rewrite everything but it's somewhat useable.
|
Thanks but i've already made a working "parser" for what i need
|
|
|
All times are GMT +1. The time now is 18:50.
|
|