2022-10-23 19:02:39 +08:00
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Xml;
|
2022-10-19 19:07:46 +08:00
|
|
|
|
using Newtonsoft.Json;
|
2022-10-23 19:02:39 +08:00
|
|
|
|
using RageCoop.Core;
|
2022-10-21 19:41:38 +08:00
|
|
|
|
using Formatting = Newtonsoft.Json.Formatting;
|
2022-10-19 19:07:46 +08:00
|
|
|
|
|
2022-11-05 18:35:39 +08:00
|
|
|
|
namespace DataDumper;
|
2022-10-23 19:02:39 +08:00
|
|
|
|
|
|
|
|
|
internal class WeaponInfo
|
2022-10-19 19:07:46 +08:00
|
|
|
|
{
|
2022-10-23 19:02:39 +08:00
|
|
|
|
public string Audio;
|
|
|
|
|
public float Damage;
|
|
|
|
|
public string DamageType;
|
|
|
|
|
public string FireType;
|
|
|
|
|
public bool IsVehicleWeapon;
|
|
|
|
|
public string Name;
|
|
|
|
|
public float Speed;
|
|
|
|
|
|
|
|
|
|
public WeaponInfo(XmlNode node)
|
2022-10-21 19:41:38 +08:00
|
|
|
|
{
|
2022-10-23 19:02:39 +08:00
|
|
|
|
if (node.Attributes["type"].Value != "CWeaponInfo") throw new Exception("Not a CWeaponInfo node");
|
|
|
|
|
foreach (XmlNode info in node.ChildNodes)
|
|
|
|
|
switch (info.Name)
|
2022-10-21 19:41:38 +08:00
|
|
|
|
{
|
2022-10-23 19:02:39 +08:00
|
|
|
|
case "Name":
|
|
|
|
|
Name = info.InnerText;
|
|
|
|
|
break;
|
|
|
|
|
case "Audio":
|
|
|
|
|
Audio = info.InnerText;
|
|
|
|
|
break;
|
|
|
|
|
case "FireType":
|
|
|
|
|
FireType = info.InnerText;
|
|
|
|
|
break;
|
|
|
|
|
case "DamageType":
|
|
|
|
|
DamageType = info.InnerText;
|
|
|
|
|
break;
|
|
|
|
|
case "Damage":
|
|
|
|
|
Damage = info.GetFloat();
|
|
|
|
|
break;
|
|
|
|
|
case "Speed":
|
|
|
|
|
Speed = info.GetFloat();
|
|
|
|
|
break;
|
2022-10-21 19:41:38 +08:00
|
|
|
|
}
|
2022-10-23 19:02:39 +08:00
|
|
|
|
|
|
|
|
|
IsVehicleWeapon = Name.StartsWith("VEHICLE_WEAPON");
|
2022-10-21 19:41:38 +08:00
|
|
|
|
}
|
2022-10-23 19:02:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static class Program
|
|
|
|
|
{
|
|
|
|
|
public static float GetFloat(this XmlNode n)
|
2022-10-19 19:07:46 +08:00
|
|
|
|
{
|
2022-10-23 19:02:39 +08:00
|
|
|
|
return float.Parse(n.Attributes["value"].Value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void Main()
|
|
|
|
|
{
|
|
|
|
|
Dictionary<uint, WeaponInfo> weapons = new();
|
|
|
|
|
foreach (var f in Directory.GetFiles("meta", "*.meta")) Parse(f, weapons);
|
|
|
|
|
Directory.CreateDirectory("Weapons");
|
|
|
|
|
File.WriteAllText("Weapons\\Weapons.json", JsonConvert.SerializeObject(weapons, Formatting.Indented));
|
|
|
|
|
DumpWeaponHash(weapons, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void Parse(string filename, Dictionary<uint, WeaponInfo> weap)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Parsing " + filename);
|
|
|
|
|
var doc = new XmlDocument();
|
|
|
|
|
try
|
2022-10-21 19:41:38 +08:00
|
|
|
|
{
|
2022-10-23 19:02:39 +08:00
|
|
|
|
doc.Load(filename);
|
2022-10-21 19:41:38 +08:00
|
|
|
|
}
|
2022-10-23 19:02:39 +08:00
|
|
|
|
catch (Exception ex)
|
2022-10-21 19:41:38 +08:00
|
|
|
|
{
|
2022-10-23 19:02:39 +08:00
|
|
|
|
Console.WriteLine(ex);
|
|
|
|
|
return;
|
2022-10-21 19:41:38 +08:00
|
|
|
|
}
|
2022-10-23 19:02:39 +08:00
|
|
|
|
|
|
|
|
|
var nodes = doc.ChildNodes.ToList();
|
|
|
|
|
if (nodes.Any(x => x.Name == "CWeaponInfoBlob"))
|
2022-10-21 19:41:38 +08:00
|
|
|
|
{
|
2022-10-23 19:02:39 +08:00
|
|
|
|
var infosNode = doc.GetElementsByTagName("Item");
|
|
|
|
|
foreach (XmlNode n in infosNode)
|
|
|
|
|
if (n.Attributes["type"]?.Value == "CWeaponInfo")
|
2022-10-21 19:41:38 +08:00
|
|
|
|
{
|
2022-10-23 19:02:39 +08:00
|
|
|
|
var info = new WeaponInfo(n);
|
|
|
|
|
if (!info.Name.StartsWith("VEHICLE_WEAPON") && !info.Name.StartsWith("WEAPON")) continue;
|
|
|
|
|
var hash = Hash(info.Name);
|
|
|
|
|
if (weap.ContainsKey(hash))
|
|
|
|
|
weap[hash] = info;
|
|
|
|
|
else
|
|
|
|
|
weap.Add(hash, info);
|
2022-10-21 19:41:38 +08:00
|
|
|
|
}
|
|
|
|
|
}
|
2022-10-23 19:02:39 +08:00
|
|
|
|
}
|
2022-10-21 19:41:38 +08:00
|
|
|
|
|
2022-10-23 19:02:39 +08:00
|
|
|
|
private static void DumpWeaponHash(Dictionary<uint, WeaponInfo> weapons, bool sort = false,
|
|
|
|
|
string path = @"Weapons\WeaponHash.cs")
|
|
|
|
|
{
|
|
|
|
|
StringBuilder output = new();
|
|
|
|
|
List<string> lines = new();
|
|
|
|
|
var weps = weapons.Where(x => x.Value.Name.StartsWith("WEAPON"));
|
|
|
|
|
var vehWeaps = weapons.Where(x => x.Value.Name.StartsWith("VEHICLE_WEAPON"));
|
|
|
|
|
output.Append("public enum WeaponHash : uint\r\n{");
|
|
|
|
|
foreach (var info in weps)
|
|
|
|
|
lines.Add($"{CoreUtils.FormatToSharpStyle(info.Value.Name, 7)} = {info.Key.ToHex()}");
|
|
|
|
|
if (sort) lines.Sort();
|
|
|
|
|
foreach (var l in lines) output.Append($"\r\n\t{l},");
|
|
|
|
|
output.AppendLine("\r\n}");
|
|
|
|
|
output.AppendLine();
|
|
|
|
|
output.Append("public enum VehicleWeaponHash : uint\r\n{\r\n\tInvalid = 0xFFFFFFFF,");
|
|
|
|
|
lines = new List<string>();
|
|
|
|
|
foreach (var info in vehWeaps)
|
|
|
|
|
lines.Add($"{CoreUtils.FormatToSharpStyle(info.Value.Name)} = {info.Key.ToHex()}");
|
|
|
|
|
if (sort) lines.Sort();
|
|
|
|
|
foreach (var l in lines) output.Append($"\r\n\t{l},");
|
|
|
|
|
output.Append("\r\n}");
|
|
|
|
|
File.WriteAllText(path, output.ToString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static List<XmlNode> ToList(this XmlNodeList l)
|
|
|
|
|
{
|
|
|
|
|
var nodes = new List<XmlNode>();
|
|
|
|
|
foreach (XmlNode n in l) nodes.Add(n);
|
|
|
|
|
return nodes;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static uint Hash(string key)
|
|
|
|
|
{
|
|
|
|
|
key = key.ToLower();
|
|
|
|
|
var i = 0;
|
|
|
|
|
uint hash = 0;
|
|
|
|
|
while (i != key.Length)
|
2022-10-19 19:07:46 +08:00
|
|
|
|
{
|
2022-10-23 19:02:39 +08:00
|
|
|
|
hash += key[i++];
|
|
|
|
|
hash += hash << 10;
|
|
|
|
|
hash ^= hash >> 6;
|
2022-10-19 19:07:46 +08:00
|
|
|
|
}
|
2022-10-23 19:02:39 +08:00
|
|
|
|
|
|
|
|
|
hash += hash << 3;
|
|
|
|
|
hash ^= hash >> 11;
|
|
|
|
|
hash += hash << 15;
|
|
|
|
|
return hash;
|
2022-10-19 19:07:46 +08:00
|
|
|
|
}
|
|
|
|
|
}
|