新增Item绘制接口HOOK
This commit is contained in:
parent
778f9427f2
commit
58f5d5945c
|
|
@ -1,6 +1,8 @@
|
|||
|
||||
class Rindro_Item {
|
||||
//C指针
|
||||
C_Object = null;
|
||||
//绘制信息结构体
|
||||
DrawInfo = null;
|
||||
|
||||
constructor() {
|
||||
|
||||
|
|
@ -24,6 +26,15 @@ class Rindro_Item {
|
|||
function SetIndex(Index) {
|
||||
NativePointer(C_Object).add(0x1C).writeInt(Index);
|
||||
}
|
||||
//获取名字
|
||||
function GetName() {
|
||||
local NamePointer = NativePointer(C_Object).add(0x20).readInt();
|
||||
return NativePointer(L_sq_I2P(NamePointer)).readUnicodeString();
|
||||
}
|
||||
//获取品级
|
||||
function GetRarity() {
|
||||
return NativePointer(C_Object).add(0xF4).readInt();
|
||||
}
|
||||
//获取强化值
|
||||
function GetUpgrade() {
|
||||
return MemoryTool.DecodeMemoryData(C_Object + 0x1054);
|
||||
|
|
@ -64,4 +75,172 @@ class Rindro_Item {
|
|||
function SetEnchanting(Enchanting) {
|
||||
MemoryTool.EncodeMemoryData(C_Object + 0x1084, Enchanting);
|
||||
}
|
||||
}
|
||||
//读取Uuid
|
||||
function GetUuid() {
|
||||
return NativePointer(C_Object).add(0x206).readInt();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//是否为装备
|
||||
function IsEquip() {
|
||||
return NativePointer(C_Object).add(0x4).readInt() == 2;
|
||||
}
|
||||
|
||||
//是否为消耗品
|
||||
function IsStack() {
|
||||
return NativePointer(C_Object).add(0x4).readInt() == 1;
|
||||
}
|
||||
|
||||
|
||||
function ConstructDrawingInformation(...) {
|
||||
if (!DrawInfo) {
|
||||
DrawInfo = Rindro_Item_DrawInfo(this);
|
||||
if (vargc > 0) {
|
||||
DrawInfo.AddGuidanceInformation(vargv[0]);
|
||||
}
|
||||
DrawInfo.Init();
|
||||
}
|
||||
}
|
||||
|
||||
function Show(X, Y) {
|
||||
//背景框
|
||||
Rindro_BaseToolClass.DrawNineBox(X, Y, 214, DrawInfo.Height + 30, "interface2/common/mypopup/popup.img", 0);
|
||||
// local C_Object = Rindro_Image_GlobalMap["popup"].GetPng(134);
|
||||
// print(C_Object);
|
||||
// L_Sq_CallFunc(0x11DF050, "void", FFI_FASTCALL, ["pointer", "int", "int", "int", "int", "int"], C_Object, 0, 10, 10, 10, 10);
|
||||
|
||||
foreach(info in DrawInfo.InfoList) {
|
||||
//文字
|
||||
if (info.Type == 0) {
|
||||
L_sq_DrawCode(info.Content, X + info.X, Y + info.Y, info.Color, 0, 1);
|
||||
} else if (info.Type == 1) {
|
||||
Rindro_Image_GlobalMap["popup"].DrawPng(270, X + info.X, Y + info.Y);
|
||||
} else if (info.Type == 2) {
|
||||
info.Func(X + info.X, Y + info.Y, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Rindro_Item_DrawInfo {
|
||||
//Item对象
|
||||
Item = null;
|
||||
//指导信息 (原装备生成的信息)
|
||||
GuidanceInformation = null;
|
||||
//指导信息标志位
|
||||
GuidanceInformationFlag = 0;
|
||||
//信息
|
||||
InfoList = null;
|
||||
|
||||
Height = 0;
|
||||
|
||||
Padding = 8;
|
||||
|
||||
constructor(gItem) {
|
||||
Item = gItem;
|
||||
InfoList = [];
|
||||
}
|
||||
|
||||
//添加指导信息
|
||||
function AddGuidanceInformation(info) {
|
||||
GuidanceInformation = info;
|
||||
}
|
||||
|
||||
function Init() {
|
||||
|
||||
//读取强化等级
|
||||
local UpgradeLevel = Item.GetUpgrade();
|
||||
//读取名字
|
||||
local Name = Item.GetName();
|
||||
local UpgradeStr = UpgradeLevel > 0 ? (UpgradeLevel + " ") : "";
|
||||
local NameStr = Name.len() > 0 ? (Name + " ") : "未定名";
|
||||
|
||||
AddContent((UpgradeStr + Name), Padding, Padding, Rindro_BaseToolClass.GetRarityColor(Item.GetRarity()));
|
||||
|
||||
if (isGm()) {
|
||||
//读取编号
|
||||
local Index = Item.GetIndex();
|
||||
//读取uuid
|
||||
local Uuid = Item.GetUuid();
|
||||
local IndexStr = Index > 0 ? ("编号: [" + Index + "] ") : "";
|
||||
local UuidStr = Uuid > 10000 ? ("uid: [" + Uuid + "] ") : "";
|
||||
AddContent((IndexStr + UuidStr), Padding, 15, 0xffffffff);
|
||||
}
|
||||
|
||||
for (local i = 1; i< GuidanceInformation.len(); i++) {
|
||||
local info = GuidanceInformation[i];
|
||||
if (info.Str && info.Str.len() > 0) {
|
||||
local RealStr = format(info.Str);
|
||||
if (info.Flag != GuidanceInformationFlag) {
|
||||
AddContent(RealStr, Padding, 15, info.Color);
|
||||
}
|
||||
//说明要绘制在右侧这个左侧信息已经绘制过了
|
||||
else {
|
||||
local StrLength = LenheartTextClass.GetStringLength(RealStr);
|
||||
AddContent(RealStr, 215 - StrLength - Padding, 0, info.Color);
|
||||
}
|
||||
} else {
|
||||
AddDividing(26, 15);
|
||||
//第二道分割线下面
|
||||
if (GuidanceInformationFlag > 4) {
|
||||
//有自定义的代理内容则添加
|
||||
if (getroottable()["NewItemInfoWindow_Obj"].CustomDrawDelegate.len() > 0) {
|
||||
//真正达成条件需要代理的Item
|
||||
local RealCustomDrawDelegate = [];
|
||||
//先遍历一遍检查条件是否成立
|
||||
foreach(Name, Info in getroottable()["NewItemInfoWindow_Obj"].CustomDrawDelegate) {
|
||||
if (Info.CheckFunc(Item) == true) RealCustomDrawDelegate.append(Info);
|
||||
}
|
||||
//需要代理的项
|
||||
if (RealCustomDrawDelegate.len() > 0) {
|
||||
foreach(Info in RealCustomDrawDelegate) {
|
||||
AddDelegate(Info.Height, Info.Func);
|
||||
}
|
||||
AddDividing(26, 15);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
GuidanceInformationFlag = info.Flag;
|
||||
}
|
||||
}
|
||||
|
||||
//增加内容
|
||||
function AddContent(Content, X, Y, Color) {
|
||||
InfoList.append({
|
||||
Type = 0,
|
||||
Content = Content,
|
||||
X = X,
|
||||
Y = Y + Height,
|
||||
Color = Color
|
||||
});
|
||||
|
||||
Height += Y;
|
||||
}
|
||||
|
||||
//增加分割线
|
||||
function AddDividing(X, Y) {
|
||||
InfoList.append({
|
||||
Type = 1,
|
||||
X = X,
|
||||
Y = Y + Height + 3,
|
||||
});
|
||||
|
||||
Height += 8;
|
||||
}
|
||||
|
||||
//增加自定义代理
|
||||
function AddDelegate(Y, Func) {
|
||||
InfoList.append({
|
||||
Type = 2,
|
||||
X = 0,
|
||||
Y = Height,
|
||||
Func = Func
|
||||
});
|
||||
Height += Y;
|
||||
}
|
||||
}
|
||||
|
||||
getroottable().rawdelete("NewItemInfoWindow_Obj");
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
文件名:NewItemInfoWindow.nut
|
||||
路径:Project/NewItemInfoWindow/NewItemInfoWindow.nut
|
||||
创建日期:2026-01-18 11:22
|
||||
文件用途:
|
||||
*/
|
||||
class NewItemInfoWindowC extends Rindro_BaseToolClass {
|
||||
|
||||
|
||||
|
||||
//绘制信息Map
|
||||
DrawInfoMap = null;
|
||||
//Script信息
|
||||
ScriptInfoMap = null;
|
||||
|
||||
//自定义绘制代理
|
||||
CustomDrawDelegate = null;
|
||||
|
||||
Img = Rindro_Image("soulweapon/main.img");
|
||||
|
||||
constructor() {
|
||||
DrawInfoMap = {};
|
||||
ScriptInfoMap = {};
|
||||
CustomDrawDelegate = {};
|
||||
Fix();
|
||||
|
||||
AddDelegate("测试代理", 28, function(X, Y, Item) {
|
||||
L_sq_DrawCode("灵魂救赎阶段: 1 / 3", X + 6, Y + 15, sq_RGBA(255, 0, 240, 255), 0, 1);
|
||||
L_sq_DrawCode("封印灵魂数: ", X + 6, Y + 30, sq_RGBA(104, 213, 237, 255), 0, 1);
|
||||
L_sq_DrawCode("100%", X + 180, Y + 30, sq_RGBA(255, 119, 0, 255), 0, 1);
|
||||
Img.DrawPng(0, X + 70, Y + 34);
|
||||
Img.DrawPng(1, X + 72, Y + 36);
|
||||
}.bindenv(this), function(Item) {
|
||||
if (Item.GetIndex() == 104000046) return true;
|
||||
return false;
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
//绘制Info
|
||||
function Show(InfoList, EquipAddress, XPos, YPos) {
|
||||
if (!DrawInfoMap.rawin(EquipAddress)) {
|
||||
local ItemObject = Rindro_Item();
|
||||
ItemObject.LoadByAddress(EquipAddress);
|
||||
ItemObject.ConstructDrawingInformation(InfoList);
|
||||
DrawInfoMap.rawset(EquipAddress, ItemObject);
|
||||
}
|
||||
DrawInfoMap[EquipAddress].Show(XPos, YPos);
|
||||
}
|
||||
|
||||
function AddDelegate(Name, Height, Func, CheckFunc) {
|
||||
CustomDrawDelegate.rawset(Name, {
|
||||
//代理区域高度
|
||||
Height = Height,
|
||||
//代理回调函数
|
||||
Func = Func,
|
||||
//代理条件
|
||||
CheckFunc = CheckFunc
|
||||
})
|
||||
}
|
||||
|
||||
function RemoveDelegate(Name) {
|
||||
CustomDrawDelegate.rawdelete(Name);
|
||||
}
|
||||
|
||||
function Fix() {
|
||||
NativePointer(0xF363D9).writeByteArray(array(16, 0x90))
|
||||
Rindro_Haker.LoadHook(0xF363D0, ["int", "int", "int", "void"],
|
||||
function(args) {
|
||||
//先获取到 DrawItemContent_F36110 的 a3参数
|
||||
local a3 = L_sq_P2I(Rindro_Haker.CpuContext.ecx) + 0x17c;
|
||||
|
||||
//计算
|
||||
//数据头尾指针 一个元素 72字节
|
||||
local Start = NativePointer(a3).add(0x4).readInt();
|
||||
local End = NativePointer(a3).add(0x8).readInt();
|
||||
//数据数组长度
|
||||
local Length = ((End - Start) / 72);
|
||||
|
||||
//原数据
|
||||
local InfoList = [];
|
||||
//获取装备编号 (遍历所有数据块 找到标志位 读取装备指针)
|
||||
local EquipAddress = 0;
|
||||
for (local i = 1; i< Length; i++) {
|
||||
local Info = {};
|
||||
|
||||
local Str = null;
|
||||
if (NativePointer(Start).add(72 * i + 0x24).readInt()< 8) {
|
||||
local StrPointer = NativePointer(Start).add(72 * i + 0x10);
|
||||
if (L_sq_P2I(StrPointer.C_Object) > 0x400000) {
|
||||
Str = StrPointer.readUnicodeString();
|
||||
}
|
||||
} else {
|
||||
local StrPointer = NativePointer(Start).add(72 * i + 0x10).readInt();
|
||||
if (StrPointer > 0x400000) {
|
||||
Str = NativePointer(StrPointer).readUnicodeString();
|
||||
}
|
||||
}
|
||||
Info.Str <- Str;
|
||||
Info.Flag <- NativePointer(Start).add(72 * i).readInt();
|
||||
|
||||
local Pos = NativePointer(Start).add(72 * i + 0x4).readInt();
|
||||
local Color = NativePointer(Start).add(72 * i + 0x8).readInt();
|
||||
|
||||
//特殊的位置信息 作为标志位的时候 颜色是装备指针
|
||||
if (Pos == 947330670) {
|
||||
EquipAddress = Color;
|
||||
}
|
||||
|
||||
Info.Color <- Color;
|
||||
InfoList.append(Info);
|
||||
}
|
||||
|
||||
if (EquipAddress != 0) {
|
||||
// printf("装备编号: " + NativePointer(EquipAddress).add(0x1c).readInt());
|
||||
local XPos = NativePointer(L_sq_P2I(Rindro_Haker.CpuContext.esi) + 0x14).readInt();
|
||||
local YPos = NativePointer(L_sq_P2I(Rindro_Haker.CpuContext.esi) + 0x18).readInt();
|
||||
Show(InfoList, EquipAddress, XPos, YPos);
|
||||
//HOOK原逻辑不执行
|
||||
NativePointer(0xF363D9).writeByteArray(array(16, 0x90))
|
||||
}
|
||||
|
||||
return null;
|
||||
}.bindenv(this),
|
||||
function(args) {
|
||||
//还原原逻辑
|
||||
NativePointer(0xF363D9).writeByteArray([0x80, 0xBE, 0x90, 0x01, 0x00, 0x00, 0x00, 0x74, 0x0E, 0xC6, 0x86, 0x90, 0x01, 0x00, 0x00, 0x00]);
|
||||
return null;
|
||||
}.bindenv(this));
|
||||
|
||||
//构造信息时
|
||||
Rindro_Haker.LoadHook(0xF542F0, ["int", "int", "int", "int", "int"],
|
||||
function(args) {
|
||||
//找到新增分割线的构造时机 将标志位写入位置参数 将Item地址写入颜色参数
|
||||
if (args[0] > 0) {
|
||||
if (NativePointer(args[1]).readUnicodeString().len() <= 0) {
|
||||
local EquipmentAddress = NativePointer(Rindro_Haker.CpuContext.ecx).add(0x178).readInt();
|
||||
//是装备才做这个事
|
||||
if (NativePointer(EquipmentAddress).add(0x4).readInt() == 2) {
|
||||
args[2] = 947330670;
|
||||
args[3] = EquipmentAddress;
|
||||
return args;
|
||||
}
|
||||
}
|
||||
}
|
||||
}.bindenv(this),
|
||||
function(args) {
|
||||
|
||||
return null;
|
||||
}.bindenv(this));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
getroottable().rawdelete("NewItemInfoWindow_Obj");
|
||||
|
||||
|
||||
function Lenheart_NewItemInfoWindow_Fun(obj) {
|
||||
local RootTab = getroottable();
|
||||
if (!RootTab.rawin("NewItemInfoWindow_Obj")) {
|
||||
RootTab.rawset("NewItemInfoWindow_Obj", NewItemInfoWindowC());
|
||||
}
|
||||
}
|
||||
|
||||
getroottable()["LenheartFuncTab"].rawset("NewItemInfoWindowFuncN", Lenheart_NewItemInfoWindow_Fun);
|
||||
Loading…
Reference in New Issue