local ffi = require("ffi")
local read = function(typename, address)
if address == nil then
return function(address)
return ffi.cast(ffi.typeof(typename.."*"), ffi.cast("uint32_t ", address))[0]
end
end
return ffi.cast(ffi.typeof(typename.."*"), ffi.cast("uint32_t ", address))[0]
end
local follow_call = function(ptr)
local insn = ffi.cast("uint8_t*", ptr)
if insn[0] == 0xE8 then
-- relative, displacement relative to next instruction
local offset = ffi.cast("int32_t*", insn+1)[0]
return insn + offset + 5
elseif insn[0] == 0xFF and insn[1] == 0x15 then
-- absolute
local call_addr = ffi.cast("uint32_t**", ffi.cast("const char*", ptr)+2)
return call_addr[0][0]
elseif insn[0] == 0xB0 then
return ffi.cast("uint32_t", ptr + 4 + read("uint32_t", ptr))
else
error(string.format("unknown instruction to follow: %02X!", insn[0]))
end
end
local string_t = [[struct {
char* buffer;
int capacity;
int grow_size;
int length;
}]]
local paint_kit_t = [[struct {
int nID;
]].. string_t ..[[ name;
]].. string_t ..[[ description;
]].. string_t ..[[ tag;
]].. string_t ..[[ same_name_family_aggregate;
]].. string_t ..[[ pattern;
]].. string_t ..[[ normal;
]].. string_t ..[[ logoMaterial;
bool baseDiffuseOverride;
int rarity;
int style;
uint8_t color[4][4];
char pad[35];
float wearRemapMin;
float wearRemapMax;
}]]
local create_map_t = function(key_type, value_type)
return ffi.typeof([[struct {
void* lessFunc;
struct {
struct {
int left;
int right;
int parent;
int type;
$ key;
$ value;
}* memory;
int allocationCount;
int growSize;
} memory;
int root;
int num_elements;
int firstFree;
int lastAlloc;
struct {
int left;
int right;
int parent;
int type;
$ key;
$ value;
}* elements;
}
]], ffi.typeof(key_type), ffi.typeof(value_type), ffi.typeof(key_type), ffi.typeof(value_type))
end
item_schema_t = ffi.typeof([[struct {
$ paint_kits;
}*]],
create_map_t("int", paint_kit_t.."*"))
local get_item_schema_addr = client.find_signature("client.dll", "\xA1\xCC\xCC\xCC\xCC\x85\xC0\x75\x53") or error("cant find get_item_scham()")
local get_item_schema_fn = ffi.cast("uint32_t(__stdcall*)()", get_item_schema_addr)
local get_paint_kit_definition_addr = client.find_signature("client.dll", "\xE8\xCC\xCC\xCC\xCC\x8B\xF0\x8B\x4E\x7C") or error("cant find get_paint_kit_definition")
local get_paint_kit_definition_fn = ffi.cast("void*(__thiscall*)(void*, int)", follow_call(get_paint_kit_definition_addr))
local item_schema_c = {}
function item_schema_c.create(ptr)
return setmetatable({
ptr = ptr,
}, {
__index = item_schema_c,
__metatable = "item_schema"
})
end
function item_schema_c:get_paint_kit(index)
local paint_kit_addr = get_paint_kit_definition_fn(self.ptr, index)
if paint_kit_addr == nil then return end
return ffi.cast(ffi.typeof(paint_kit_t .. "*"), paint_kit_addr)
end
local schema = item_schema_c.create(ffi.cast(item_schema_t, get_item_schema_fn()+4));
local ctx = {
vars = {
colors = {
ui.new_color_picker('SKINS', 'Weapon skin', '1', 255, 255, 255, 255),
ui.new_color_picker('SKINS', 'Weapon skin', '2', 255, 255, 255, 255),
ui.new_color_picker('SKINS', 'Weapon skin', '3', 255, 255, 255, 255),
ui.new_color_picker('SKINS', 'Weapon skin', '4`', 255, 255, 255, 255)
},
reset_colors = nil,
},
refs = {
skins_enabled = ui.reference('SKINS', 'Weapon skin', 'Enabled'),
skins_weapon_skin = ui.reference('SKINS', 'Weapon skin', 'Skin'),
},
paint_kits = {},
o_pk_colors = {},
current_paintkit = nil,
set_paintkit_color = function( obj, r, g, b, a )
obj[ 0 ] = r;
obj[ 1 ] = g;
obj[ 2 ] = b;
obj[ 3 ] = a;
end,
set_paintkit_color_obj = function( obj1, ojb2 )
obj1[ 0 ] = ojb2[ 0 ];
obj1[ 1 ] = ojb2[ 1 ];
obj1[ 2 ] = ojb2[ 2 ];
obj1[ 3 ] = ojb2[ 3 ];
end,
set_menu_color = function(ref, obj )
ui.set(ref, obj[ 0 ], obj[ 1 ], obj[ 2 ], obj[ 3 ])
end,
}
local init = function()
for i = 1, 4000 do
local num = i;
if num >= 3000 then
num = num + 10000;
end
local paint_kit = schema:get_paint_kit(num);
if paint_kit ~= nil then
local copy = ffi.new( "uint8_t[4][4]" );
ctx.set_paintkit_color( copy, paint_kit.color[ 0 ], paint_kit.color[ 1 ], paint_kit.color[ 2 ], paint_kit.color[ 3 ] );
table.insert( ctx.paint_kits, paint_kit.nID, paint_kit );
table.insert( ctx.o_pk_colors, paint_kit.nID, copy );
end
end
ctx.current_paintkit = ui.get(ctx.refs.skins_weapon_skin)
end
init()
local force_update = function()
ui.set(ctx.refs.skins_enabled, false)
client.delay_call(0.6, ui.set, ctx.refs.skins_enabled, true)
end
local set_paintkit_colors = function( paintkit )
for x = 1, 4 do
ctx.set_paintkit_color( ctx.paint_kits[ paintkit ].color[ x - 1 ], ui.get(ctx.vars.colors[ x ]) )
end
end
local set_menu_colors = function( obj )
for x = 1, 4 do
ctx.set_menu_color( ctx.vars.colors[ x ], obj[ x - 1 ] )
end
end
local reset_paintkit_colors = function( paintkit )
set_menu_colors( ctx.o_pk_colors[ paintkit ] )
end
local color_cb = function()
set_paintkit_colors( ctx.current_paintkit )
force_update()
end
local weapon_skin_cb = function()
ctx.current_paintkit = ui.get(ctx.refs.skins_weapon_skin)
set_menu_colors( ctx.paint_kits[ ctx.current_paintkit ].color )
set_paintkit_colors( ctx.current_paintkit );
force_update()
end
local reset_color_cb = function()
reset_paintkit_colors( ctx.current_paintkit )
set_paintkit_colors( ctx.current_paintkit );
force_update()
end
ctx.vars.reset_colors = ui.new_button('SKINS', 'Weapon skin', 'Reset color', reset_color_cb)
ui.set_callback(ctx.refs.skins_weapon_skin, weapon_skin_cb )
ui.set_callback(ctx.vars.colors[ 1 ], color_cb )
ui.set_callback(ctx.vars.colors[ 2 ], color_cb )
ui.set_callback(ctx.vars.colors[ 3 ], color_cb )
ui.set_callback(ctx.vars.colors[ 4 ], color_cb )