Jump to content

Recommended Posts

  • Members
Posted
4 hours ago, wq223 said:

Maybe there is hope for lua files. As for other files, most of them are models and textures.

I tried searching for the phrase "¿Estás seguro de que quieres salir del juego?" with your tool, but without success...

Perhaps it's just me who can't get it to work.

 

 

  • Members
Posted
On 11/26/2025 at 5:40 AM, Kizurin said:

have you try data files on wherewindsmeet\wwm\wwm_standard\LocalData\Patch\HD\oversea ?

I have tried several tools, but I can only extract readable text in .json with wwm_utils.exe.

If you could show me how to do this, I would be grateful.

Posted

@wq223 I has a `luac` file, can you help convert to lua text?

On 11/29/2025 at 4:12 AM, wq223 said:

Maybe there is hope for lua files. As for other files, most of them are models and textures.

I has a `luac` file, can you help convert to lua text?

  • Supporter
Posted
3 hours ago, und3fy said:

@wq223 I has a `luac` file, can you help convert to lua text?

I has a `luac` file, can you help convert to lua text?

Send file

Posted
15 hours ago, Unlock777 said:

I have tried several tools, but I can only extract readable text in .json with wwm_utils.exe.

If you could show me how to do this, I would be grateful.

wherewindsmeet\wwm\wwm_standard\LocalData\Patch\HD

Example of extracting text from a data file by offset

.thumb.png.d406fb740bed500dd7ae49c5b8e903b3.png

wherewindsmeet\wwm\wwm_standard\LocalData\Patch\HD\oversea

There is also a data file in this directory, but the extracted text looks like some secondary revisions of entries.

 

Hotfix text, UI text, and event text are all contained within these data files.

1. Use wq223's Python script to decompress these data files.

2. Find a way to convert the exported .dat file into serialized text.

There are several different offsets, and the header also has several variations. I only crudely exported the text and haven't thoroughly researched how to modify, package, and replace it.

i. 20**00
ii. 08**00
** represents the string length.

  • Members
Posted
9 hours ago, Kizurin said:

wherewindsmeet\wwm\wwm_standard\LocalData\Patch\HD

Example of extracting text from a data file by offset

.thumb.png.d406fb740bed500dd7ae49c5b8e903b3.png

wherewindsmeet\wwm\wwm_standard\LocalData\Patch\HD\oversea

There is also a data file in this directory, but the extracted text looks like some secondary revisions of entries.

 

Hotfix text, UI text, and event text are all contained within these data files.

1. Use wq223's Python script to decompress these data files.

2. Find a way to convert the exported .dat file into serialized text.

There are several different offsets, and the header also has several variations. I only crudely exported the text and haven't thoroughly researched how to modify, package, and replace it.

i. 20**00
ii. 08**00
** represents the string length.

Thank you for sharing, unfortunately it is beyond my expertise.

Posted

Hi everyone,

I've successfully unpacked the game files using the tools mentioned in this thread and got the entries.json and tables folder. I've translated the entries.json file to my language.Now I'm wondering: How do I repack the translated entries.json back into the game?

  • Supporter
Posted
1 hour ago, und3fy said:

here bro, This zip of 3 files luac

Archive.zip 16.94 kB · 3 downloads

They use modified opcodes so normal decompilation cannot be performed, but disassembly is possible and I am currently reverse engineering the luac decompilation

Okay, I can decompile the two files you provided, but there should be errors because I haven't completed the opcode modification work yet.

Posted
16 minutes ago, wq223 said:

They use modified opcodes so normal decompilation cannot be performed, but disassembly is possible and I am currently reverse engineering the luac decompilation

Okay, I can decompile the two files you provided, but there should be errors because I haven't completed the opcode modification work yet.

Now i use Grok for try decompile, maybe not correct logic but i think 90% logic or function is correct. 
However, can you share your tools?
 

  • Supporter
Posted

Local data is stored in the db_mp file. This database encrypts the text part. I wrote a script to export the contents as much as possible.

Please put the db_mp file in the same directory as the script, and then run the script directly

Please make sure to install sqlite3 and msgpack before doing this

format_hotfix_data.py

  • Supporter
Posted (edited)
22 minutes ago, und3fy said:

Now i use Grok for try decompile, maybe not correct logic but i think 90% logic or function is correct. 
However, can you share your tools?
 

It must be wrong that you did not redirect the file, because what you provided to ai is the luac version with unmodified opcodes, and what ai provides can only be a script output by guessing, which should be a bit of a test of ai's processing capabilities

It is correct to use AI, but as far as possible under the right circumstances, provide those parts that cannot be processed anyway. Our purpose may just be to get some logic

Edited by wq223
Posted
13 minutes ago, wq223 said:

It must be wrong that you did not redirect the file, because what you provided to ai is the luac version with unmodified opcodes, and what ai provides can only be a script output by guessing, which should be a bit of a test of ai's processing capabilities

It is correct to use AI, but as far as possible under the right circumstances, provide those parts that cannot be processed anyway. Our purpose may just be to get some logic

Thanks for your tool, it's offline way for get hotfix and lua patch. I hooked to lua process for capture lua bytecode and lua text (image below).

My target is find function generate `translate_words_map` and save it to `.../LocalData/Patch/HD/locale`

Screenshot2025-12-02at14_45_06.thumb.png.b6302d75efa9f0cb069ed72afad21810.png

  • Supporter
Posted (edited)
44 minutes ago, wq223 said:

It must be wrong that you did not redirect the file, because what you provided to ai is the luac version with unmodified opcodes, and what ai provides can only be a script output by guessing, which should be a bit of a test of ai's processing capabilities

The script has been updated and is now output in Lua format whenever possible.

 

format_hotfix_data.py

Edited by wq223
  • Like 1
Posted
5 hours ago, wq223 said:

The script has been updated and is now output in Lua format whenever possible.

 

format_hotfix_data.py 15.27 kB · 10 downloads

I got lua file but now need decompile byte code of hotfix_manager: `G.hotfix_manager:update_table(table_data)`

this is content of `hotfix_manager.lua` (AI decompiler version), i attach bycode version, can you decompile it?
 

local require = require
local hex_object = require("hexm.client.h")
local HexObject = require("hexm.common.hex_object")
local cjson = require("cjson")
local util = require("hexm.common.util.util")
local TimerManager = require("hexm.client.manager.timer_manager").TimerManager
local DateTimeManager = require("hexm.common.datetime_manager").DateTimeManager
local patch_utils = require("patch.patch_utils")
local cmsgpack = require("cmsgpack")
local patch_config = require("patch.patch_config")

local class = class

local HotfixDataProxy = class("HotfixDataProxy", HexObject)

function HotfixDataProxy:ctor(data_object)
    self.data_object = data_object
    self.n_rows = data_object.n_rows
    self.r_rows = data_object.r_rows
    self.n_values = data_object.n_values
    self.r_values = data_object.r_values
    self.table_data = {}
end

function HotfixDataProxy:remove_row(row_id)
    self.r_rows:append(row_id)
end

function HotfixDataProxy:add_row(row_id, row_data)
    self.n_rows[row_id] = row_data
end

function HotfixDataProxy:remove_value(row_id, col_id, row_data)
    if row_data.get then
        local type_val = row_data:get("type")
        if type_val ~= "dict" then
            G.__G__TRACKBACK__("remove value is error, because the row_data is not dict!!")
        end
    end
    self.r_values:append({row_id, col_id})
end

function HotfixDataProxy:add_value(row_id, col_id, value, row_data)
    if row_data.get then
        local type_val = row_data:get("type")
        if type_val ~= "dict" then
            G.__G__TRACKBACK__("remove value is error, because the row_data is not dict!!")
        end
    end
    self.n_values[{row_id, col_id}] = value
end

function HotfixDataProxy:commit()
    return {
        name = self.data_object:get("__table_name"),
        n_rows = self.n_rows,
        r_rows = self.r_rows,
        n_values = self.n_values,
        r_values = self.r_values,
        datam = "store_hotfix"
    }
end

local HotfixManager = class("HotfixManager", HexObject)

function HotfixManager:ctor()
    self.super.ctor(self)
    self._timer_mgr = TimerManager
    self._fetch_timerid = nil
    self._script_version = tostring(self:get_script_version())
    self._cur_hotfix_idx = 0
    self._hotfix_id_data_list_need_fetch = {}
    self._hotfix_id_data_list = {}
    self._fetch_hotfix_batch_size = 12
    self._exec_list = {}
    self._mark_exec_list = {}
    self._launch_hotfix_done = false
    self._fetch_cb = nil
    self._localdb_data = {}
    self._is_localdb_data_dirty = false
    self._max_delay = 15.0
    
    if self.is_publish and MPatch.FileExistInSystem(LocalData .. "uwsgi_img") then
        -- Logic for loading hotfix data
    end
end

function HotfixManager:get_script_version()
    local data_object = {}
    require("patch.patch_config")
    
    if self.is_publish then
        if MPatch.FileExistInSystem(LocalData .. "hotfix_version.json") then
            local raw_data = MPatch.GetRawDataInSystem(LocalData .. "hotfix_version.json")
            local json_data = cjson_decode(raw_data)
            if json_data.get then
                local script_version = json_data:get("script_version")
                return tostring(script_version)
            end
        end
    end
    
    local patch_md5_file = "patchmd5.txt"
    local data = MPatch.GetRawDataInPatch(patch_md5_file)
    if not data then
        data = MPatch.GetRawDataInPackage(patch_md5_file)
    end
    
    local patch_utils = require("patch.patch_utils")
    local read_decompress_data = patch_utils.read_decompress_data
    local config_dict = cjson
    
    local ret = bool(try_catch_call(function()
        data = read_decompress_data(data)
        config_dict = cjson_decode(data)
    end))
    
    if not ret then
        G.logger:error("hotfix", "get_script_version err")
        return ""
    end
    
    return ""
end

function HotfixManager:add_timer_start_fetch_hotfix()
    if self._fetch_timerid then
        self._fetch_timerid:cancel()
    end
    
    local delay = math.random() * self._max_delay
    G.logger:info("hotfix", "add_timer_start_fetch_hotfix delay %s", delay)
    self._fetch_timerid = self._timer_mgr:add_timer(delay, function()
        self:start_fetch_hotfix()
    end)
end

function HotfixManager:start_fetch_hotfix()
    if self._fetch_timerid then
        self._fetch_timerid:cancel()
        self._fetch_timerid = nil
    end
    
    self._cur_hotfix_idx = 0
    
    G.logger:info("hotfix", "start_fetch_hotfix _cur_hotfix_idx %s", self._cur_hotfix_idx)
    
    if not self:hotfix_enable() then
        self:start_main()
        return
    end
    
    G.logger:info("hotfix", "start_fetch_hotfix %s %s", self._script_version, 0)
    
    self._hotfix_id_data_list_need_fetch = {}
    self._hotfix_id_data_list = {}
    
    G.uwsgi_manager:fetch_hotfix_list(function(guid, result, pack)
        self:_fetch_hotfix_list_callback(guid, result, pack)
    end)
end

function HotfixManager:_fetch_hotfix_list_callback(fetch_cb)
    self._fetch_cb = fetch_cb
end

function HotfixManager:load_local_hotfix_data_and_return()
    local hotfix_data = self._localdb_data:get("version")
    
    if hotfix_data ~= self._script_version then
        local localdb = G.localdb
        local hotfix_meta = localdb:get_global("hotfix_meta")
        local hotfix_id_d = hotfix_meta["hotfix_id_d"]
        
        for hotfix_id, _ in pairs(hotfix_id_d) do
            localdb:remove_global(self:get_hotfix_db_key(hotfix_id))
        end
        
        localdb:set_global(self:get_hotfix_db_key("hotfix_meta"), {})
        localdb:get_global_db_recheck()
        
        self._localdb_data = {}
        self._is_localdb_data_dirty = false
    else
        G.logger:error("hotfix", "load_local_hotfix_data_and_return hotfix_data err %s %s", hotfix_data, self._script_version)
    end
    
    local hotfix_id_2_data = {}
    
    for hotfix_id, hotfix_data in pairs(hotfix_meta["hotfix_id_d"]) do
        hotfix_id_2_data[hotfix_id] = localdb:get_global(self:get_hotfix_db_key(hotfix_id))
    end
    
    return hotfix_id_2_data
end

function HotfixManager:update_local_hotfix_data(hotfix_id, hotfix_data)
    if not self._is_localdb_data_dirty then
        G.logger:info("hotfix", "update_local_hotfix_data %s", hotfix_id)
        
        self:load_local_hotfix_data_and_return()
        self._is_localdb_data_dirty = true
    end
end

function HotfixManager:try_save_local_hotfix_data()
    if not self._is_localdb_data_dirty then
        return
    end
    
    G.logger:info("hotfix", "try_save_local_hotfix_data saved", true)
    
    local version = self._script_version
    local hotfix_meta = {"version": version, "hotfix_id_d": {}}
    
    local hotfix_id_2_data = self:load_local_hotfix_data_and_return()
    
    for hotfix_id, keys in pairs(hotfix_id_2_data) do
        if keys == "HOTFIX_DATA_ALREADY_SAVED" then
            hotfix_meta["hotfix_id_d"][hotfix_id] = self:get_hotfix_db_key(hotfix_id)
        end
    end
    
    local localdb = G.localdb
    for hotfix_id, _ in pairs(hotfix_meta["hotfix_id_d"]) do
        localdb:set_global(self:get_hotfix_db_key(hotfix_id), hotfix_id_2_data[hotfix_id])
    end
    
    localdb:clear_global_cache(1)
    localdb:set_global("hotfix_meta", hotfix_meta)
end

function HotfixManager:ensure_hotfix_data(hotfix_id)
    local hotfix_id_2_data = self:load_local_hotfix_data_and_return()
    local hotfix_data = hotfix_id_2_data:get("HOTFIX_DATA_ALREADY_SAVED")
    
    if not hotfix_data then
        return nil
    end
    
    return self:get_hotfix_db_key(hotfix_id)
end

function HotfixManager:exec_hotfix_id_list(hotfix_id_data_list)
    local now_int = DateTimeManager:now_int()
    
    for _, hotfix_id_data in pairs(hotfix_id_data_list) do
        local hotfix_id = hotfix_id_data:get("hotfix_id")
        
        if not hotfix_id then
            G.logger:error("hotfix", "exec_hotfix_id_list hotfix_id nil %s", hotfix_id_data)
            goto continue
        end
        
        if self._exec_list:contains(hotfix_id) then
            G.logger:info("hotfix", "exec_hotfix_id_list hotfix already exec %s", hotfix_id)
            goto continue
        end
        
        local pc_patch_version = hotfix_id_data["pc_patch_version"]
        local android_patch_version = hotfix_id_data["android_patch_version"]
        local ios_patch_version = hotfix_id_data["ios_patch_version"]
        local pc_low2_patch_version = hotfix_id_data["pc_low2_patch_version"]
        
        local patch_version = self:choose_patch_version(pc_patch_version, android_patch_version, ios_patch_version, pc_low2_patch_version)
        
        if not bool(patch_utils.check_patch_version(patch_version, MPlatform.GetOsName())) then
            G.logger:error("hotfix", "patch version check failed %s %s %s", hotfix_id, patch_version, MPlatform.GetOsName())
            goto continue
        end
        
        self:ensure_hotfix_data(hotfix_id)
        
        local hotfix_data = self:ensure_hotfix_data(hotfix_id)
        
        if not hotfix_data then
            G.logger:error("hotfix", "exec_hotfix_id_list hotfix_data not exist %s", hotfix_id)
            goto continue
        end
        
        G.logger:info("hotfix", "exec_hotfix_id_list exec %s", hotfix_id)
        
        local result = try_catch_call(function()
            util.eval_hotfix(hotfix_data, hotfix_id)
        end)
        
        if not result then
            G.logger:error("hotfix", "exec_hotfix_id_list exec err %s", hotfix_id)
            G.sdk_manager:report_sa_log("Hotfix", {
                state_name = "exec_hotfix_err",
                hotfix_id_data = hotfix_id_data,
                hotfix_data = hotfix_data
            })
        end
        
        self._exec_list:append(hotfix_id)
        
        ::continue::
    end
end

function HotfixManager:start_main()
    G.sdk_manager:report_sa_log("Hotfix", {state_name = "start_main"})
    
    if type(self._hotfix_id_data_list) ~= "list" then
        self:exec_hotfix_id_list(self._hotfix_id_data_list)
    end
    
    self._cur_hotfix_idx = 120
    self._hotfix_id_data_list_need_fetch = false
    
    self:try_save_local_hotfix_data()
    
    self._launch_hotfix_done = true
    
    if self._fetch_cb then
        self._fetch_cb()
        self._fetch_cb = nil
    end
    
    G.logger:info("hotfix", "start_main end")
    G.net:get_avatar().dispatcher:dispatch("E_PHOTO_TAKE_PHOTO", {})
end

function HotfixManager:choose_patch_version(pc_patch_version, android_patch_version, ios_patch_version, pc_low2_patch_version)
    if patch_utils.is_android() then
        return android_patch_version
    elseif patch_utils.is_ios() then
        return ios_patch_version
    elseif patch_utils.is_low2() then
        return pc_low2_patch_version
    end
    
    return pc_patch_version
end

function HotfixManager:_fetch_hotfix_list_callback(e_c, data)
    G.sdk_manager:report_sa_log("Hotfix", {
        state_name = "fetch_hotfix_list_callback"
    })
    
    if type(data) ~= "dict" then
        G.logger:error("hotfix", "_fetch_hotfix_list_callback %s %s", e_c, data)
        self:add_timer_start_fetch_hotfix()
        self:start_main()
        return
    end
    
    local hotfix_list = data:get("hotfix_list")
    
    for _, item in pairs(hotfix_list) do
        local result = try_catch_call(function()
            return cmsgpack.unpack(item.raw_data)
        end)
        
        if not result then
            G.logger:error("hotfix", "raw_data unpack err %s", item)
        end
    end
    
    G.logger:info("hotfix", "_fetch_hotfix_list_callback len %s", #hotfix_list)
    
    local hotfix_id_2_data = self:load_local_hotfix_data_and_return()
    
    for hotfix_id_data in hotfix_list do
        local hotfix_id = hotfix_id_data.hotfix_id
        
        if not hotfix_id then
            G.logger:error("hotfix", "_fetch_hotfix_list_callback hotfix_id nil %s", hotfix_id_data)
            goto continue
        end
        
        if self._exec_list:contains(hotfix_id) then
            G.logger:info("hotfix", "_fetch_hotfix_list_callback already exec %s", hotfix_id)
            goto continue
        end
        
        if bool(hotfix_id_2_data[hotfix_id]) then
            G.logger:info("hotfix", "_fetch_hotfix_list_callback has local data %s", hotfix_id)
        else
            G.logger:info("hotfix", "_fetch_hotfix_list_callback no local data %s", hotfix_id)
            self._hotfix_id_data_list:append(hotfix_id_data)
        end
        
        ::continue::
    end
    
    self._cur_hotfix_idx = 0
    self._hotfix_id_data_list_need_fetch = true
    self._hotfix_id_data_list = need_fetch_hotfix_id_data_list
    
    self:fetch_next_hotfix_batch()
end

function HotfixManager:fetch_next_hotfix_batch()
    if not self._hotfix_id_data_list_need_fetch then
        self:start_main()
        return
    end
    
    if self._fetch_cb then
        return
    end
    
    self._fetch_cb = try_catch_call(function()
        return self:_fetch_hotfix_batch_callback()
    end)
    
    self._cur_hotfix_idx = self._cur_hotfix_idx + 1
    
    if not self._hotfix_id_data_list_need_fetch then
        return
    end
    
    local hotfix_id_data_list = {}
    
    for i = self._cur_hotfix_idx, math.min(self._cur_hotfix_idx + self._fetch_hotfix_batch_size - 1, #self._hotfix_id_data_list) do
        local hotfix_id_data = self._hotfix_id_data_list:get(i)
        
        if hotfix_id_data then
            local hotfix_id = hotfix_id_data.hotfix_id
            local hotfix_data_len = hotfix_id_data["hotfix_data_len"]
            local pc_patch_version = hotfix_id_data["pc_patch_version"]
            local android_patch_version = hotfix_id_data["android_patch_version"]
            local ios_patch_version = hotfix_id_data["ios_patch_version"]
            local pc_low2_patch_version = hotfix_id_data["pc_low2_patch_version"]
            
            hotfix_id_data_list:append({
                hotfix_id = hotfix_id,
                hotfix_data_len = hotfix_data_len,
                pc_patch_version = pc_patch_version,
                android_patch_version = android_patch_version,
                ios_patch_version = ios_patch_version,
                pc_low2_patch_version = pc_low2_patch_version
            })
        end
    end
    
    G.uwsgi_manager:fetch_hotfix_batch(hotfix_id_data_list, function(guid, result, pack)
        self:_fetch_hotfix_batch_callback(guid, result, pack)
    end)
end

function HotfixManager:_fetch_hotfix_batch_callback(e_c, data)
    G.sdk_manager:report_sa_log("Hotfix", {
        state_name = "fetch_hotfix_batch_callback"
    })
    
    if type(data) ~= "dict" then
        G.logger:error("hotfix", "_fetch_hotfix_batch_callback %s %s", e_c, data)
        self:add_timer_start_fetch_hotfix()
        self:start_main()
        return
    end
    
    for _, item in pairs(data:get("hotfix_data_list")) do
        local hotfix_id = item.hotfix_id
        
        if bool(self:update_local_hotfix_data(hotfix_id, item.hotfix_data)) then
            G.logger:info("hotfix", "_fetch_hotfix_batch_callback hotfix_id(%s) hotfix_data(%s)", hotfix_id, item.hotfix_data)
        end
        
        G.logger:info("hotfix", "_fetch_hotfix_batch_callback item %s", item)
    end
    
    self:fetch_next_hotfix_batch()
end

function HotfixManager:update_table(diff_dict)
    G.datam:store_hotfix(diff_dict)
end

function HotfixManager:hotfixServerEntityComponent(cls, component)
    assert(cls.__components__)
    
    if not cls.__components__:contains(component) then
        cls.__components__:append(component)
    end
    
    if not cls.__component_inits__:contains(component.init) then
        cls.__component_inits__:append(component.init)
        cls.__init_component__ = component.init
    end
    
    if not cls.__component_posts__:contains(component.post) then
        cls.__component_posts__:append(component.post)
        cls.__post_component__ = component.post
    end
    
    if not cls.__component_ticks__:contains(component.tick) then
        cls.__component_ticks__:append(component.tick)
        cls.__tick_component__ = component.tick
    end
    
    if not cls.__component_finis__:contains(component.fini) then
        cls.__component_finis__:append(component.fini)
        cls.__fini_component__ = component.fini
    end
end

function HotfixManager:hotfixClientEntityTwoStageComponent(cls, component, func_name)
    local old_func = cls[func_name]
    local __cls_two_stage_component_func_dict__ = cls.__cls_two_stage_component_func_dict__ or {}
    
    for component, func_map in ipairs(__cls_two_stage_component_func_dict__) do
        for funcname, func in pairs(func_map) do
            if funcname == func_name then
                old_func = func.component_old
            end
        end
    end
end

function HotfixManager:hotfixClientEntityComponent(cls, component, func_name)
    local old_func = cls[func_name]
    local __component_func_dict__ = cls.__component_func_dict__ or {}
    
    for component, func_map in ipairs(__component_func_dict__) do
        for funcname, func in pairs(func_map) do
            if funcname == func_name then
                old_func = func.component_old
            end
        end
    end
    
    if not found and component == "hotfixClientEntityTwoStageComponent" then
        table.insert(__component_func_dict__, {component = component, funcname = func_name, func = {component_old = old_func}})
    end
end

function HotfixManager:generate_data_table_proxy(data_object)
    return HotfixDataProxy(data_object)
end

function HotfixManager:commit_new_data_table(table_name, final_dict, hotfix_data)
    if final_dict.get then
        local type_val = final_dict:get("type")
        if type_val ~= "dict" then
            G.__G__TRACKBACK__("commit_new_data_table is error, because the final_dict is not dict!!")
        end
    end
    
    G.datam:store_hotfix({
        name = table_name,
        datam = "store_hotfix"
    })
end

function HotfixManager:test_run_hotfix_script()
    local script = [[
local PlayerAvatarMember = require("hexm.client.entities.local.player_avatar_members.photo.impl_photo_data").PlayerAvatarMember
local event_consts = require("hexm.client.consts.event_consts")
local photo_consts = require("hexm.client.consts.photo_consts")
local setting_config = require("hexm.client.manager.setting.setting_config")
local render_option_consts = require("hexm.client.consts.render_option_consts")

function PlayerAvatarMember:photo_take_photo()
	if self._photo_shot_waiting_id ~= nil then
		return
	end
	
	local hd_ratio, need_hd_ratio_delay = self:_push_pc_hd_screen_shot()

	local hd_screen_shot_ratio = G.setting_manager:get_setting(setting_config.SETTING_HD_SCREEN_SHOT_RATIO)
    if hd_screen_shot_ratio > 0 then
        G.platform_manager:set_screen_shot_jpg_enable(false)
    else
	    G.platform_manager:set_screen_shot_jpg_enable(true)
    end
    
	local grey_enable = self:_photo_get_photo_grey_info("enable_freeze_frame_after_screenshot")
	if grey_enable then
		if G.engine:IsWindows() and MRender.HasGlobalOption and MRender.HasGlobalOption("EnableFreezeFrameAfterScreenShot")then
			G.engine_layer:push_global_option("EnableFreezeFrameAfterScreenShot", true, "photo_shot", render_option_consts.RENDER_OPTION_PRIORITY_UI)
		end
	end
	
	G.sound_manager:play_sound(1500185, false)
	G.camera:push_lock_yaw_flag("photo_shot")
	G.camera:push_lock_pitch_flag("photo_shot")
	if G.ui_manager.watermark_window then
		G.ui_manager.watermark_window:set_visible(false, "photo")
	end
	G.ui_manager:set_all_windows_visible(false, "photo", list("PhotoPluginWindow"))
	G.input_manager:push_key_down_enable("photo", false)
	local win = G.ui_manager:get_window_by_name("PhotoPluginWindow")
	if win and not win:is_destroyed() then
		win.controller:leave_photo_logo_mode()
		win.view:get_node("btn_point"):set_visible(false)
	end
	
	if need_hd_ratio_delay then
		local hd_screen_shot_delay = bool(G.gm_hd_screen_shot_delay) and G.gm_hd_screen_shot_delay or G.datam.photo_default_config[1]:get("hd_screen_shot_delay", 5)
		self:add_named_none_block_timer(hd_screen_shot_delay, function()
			self:photo_take_photo_screen_shot(hd_ratio)
		end, "photo_screen_shot_delay_by_hd_shot")
	else
		self:photo_take_photo_screen_shot(hd_ratio)
	end
end

function PlayerAvatarMember:photo_take_photo_screen_shot(hd_ratio)
	local callback = function(guid, result, pack) self:_photo_shot_callback(guid, result, pack, nil, hd_ratio) end
	self._photo_shot_waiting_id = G.platform_manager:screen_shot2_as_scene_rt(true, true, callback)
	
	local ensure_water_func = function()
		if grey_enable then
			if G.engine:IsWindows() and MRender.HasGlobalOption and MRender.HasGlobalOption("EnableFreezeFrameAfterScreenShot")then
				G.engine_layer:pop_global_option("EnableFreezeFrameAfterScreenShot", "photo_shot")
			end
		end
		G.ui_manager:set_all_windows_visible(true, "photo")
		if G.ui_manager.watermark_window then
			G.ui_manager.watermark_window:set_visible(true, "photo")
		end

		self:_pop_pc_hd_screen_shot()
		G.camera:pop_lock_yaw_flag("photo_shot")
		G.camera:pop_lock_pitch_flag("photo_shot")
		G.input_manager:pop_key_down_enable("photo")
		G.platform_manager:set_screen_shot_jpg_enable(false)
	end
	local ensure_time = G.engine:IsAndroid() and 10 or 5
	self:add_named_none_block_timer(ensure_time, ensure_water_func, self._photo_shot_waiting_id)
    
	self:_photo_check_achievement()
    
	local photo_setting_config = require("hexm.client.consts.photo_setting_config")
	local template_ids = self:photo_get_setting_value(photo_setting_config.PHOTO_SETTING_SIMPLE_TEMPLATE)
	if template_ids and template_ids[1] and template_ids[1] > 1 then
		G.sdk_manager:report_sa_log("take_photo", dict(template_id = template_ids[1]))
	end

	G.net:get_avatar().dispatcher:dispatch(event_consts.E_PHOTO_TAKE_PHOTO, dict())
end

function PlayerAvatarMember:_push_pc_hd_screen_shot()
	G.space:group_photo_check_all_ghost_visible(false, "photo_shot")
	if not photo_consts:is_hd_screen_shot_valid() then
		return
	end
    
	local hd_screen_shot_ratio = G.setting_manager:get_setting(setting_config.SETTING_HD_SCREEN_SHOT_RATIO)
	if not (hd_screen_shot_ratio > 0) then
		return
	end
    
	if G.engine:IsMobilePlatform() and not G.main_player:mode_change_is_single_mode()  then
		return
	end
	
	local need_hd_ratio_delay = false

	if G.engine:IsMobilePlatform() then
		if G.engine:IsIOS() or G.engine_layer:get_is_incompatible_device_for_mobile_hd_screenshot() then
			G.engine_layer:push_render_option("Sharpening", 0.5, "camera", render_option_consts.RENDER_OPTION_PRIORITY_GAMEPLAY)
			local level = G.engine_layer:get_performance_info()
			local performance_config = require("patch.performance_config")
			if level >= performance_config.IOS_NAME_TO_LEVEL["high"] then
				G.engine_layer:push_render_option("ScreenSize", 2200, "camera", render_option_consts.RENDER_OPTION_PRIORITY_GAMEPLAY)
				need_hd_ratio_delay = true
			end
		elseif G.engine:IsAndroid() then
			G.main_player:push_game_speed_config(84, "camera")
			G.engine_layer:push_render_option("EnableTSAA", "false", "camera", render_option_consts.RENDER_OPTION_PRIORITY_GAMEPLAY)
		end
	elseif G.engine:IsWindows() then
		G.engine_layer:init_sr_options("camera",render_option_consts.RENDER_OPTION_PRIORITY_GAMEPLAY)  
		G.engine_layer:push_render_option("ScreenSize", 0, "camera", render_option_consts.RENDER_OPTION_PRIORITY_GAMEPLAY)
		need_hd_ratio_delay = true
		G.engine_layer:push_render_option("ScreenScale", hd_screen_shot_ratio, "camera", render_option_consts.RENDER_OPTION_PRIORITY_GAMEPLAY)
		G.engine_layer:push_render_option("SeparateMarchingShadowScale", 1 / hd_screen_shot_ratio, "camera", render_option_consts.RENDER_OPTION_PRIORITY_GAMEPLAY)
        
		local grey_enable = self:_photo_get_photo_grey_info("enable_ui_before_screen_shot")
		if grey_enable then
			if MRender.HasGlobalOption and MRender.HasGlobalOption("EnableUIBeforeScreenShot")then
				G.engine_layer:push_global_option("EnableUIBeforeScreenShot", true, "photo_shot", render_option_consts.RENDER_OPTION_PRIORITY_UI)
			end
		end
	end

	return hd_screen_shot_ratio, need_hd_ratio_delay
end

local PlayerAvatar = require("hexm.client.entities.local.player_avatar").PlayerAvatar
PlayerAvatar.photo_take_photo = PlayerAvatarMember.photo_take_photo
PlayerAvatar.photo_take_photo_screen_shot = PlayerAvatarMember.photo_take_photo_screen_shot
PlayerAvatar._push_pc_hd_screen_shot = PlayerAvatarMember._push_pc_hd_screen_shot
	]]
    util.eval_hotfix(script)
end

function HotfixManager:test_hotfix_data()
    local hotfix_data = dict (
		['name'] = "arrows",
		['n_rows'] = dict (
			[1] = dict (
				['arrow_id'] = 1,
				['arrow_model'] = 1,
			),
			[2] = dict (
				['arrow_id'] = 2,
				['arrow_model'] = 2,
			)
		),
		['r_rows'] = list (102025, 102026),
		['r_values'] = dict (
			[102027] = list ("line_png", "arrow_model"),
			[102028] = list ("line_png", "arrow_model", "arrow_name")
		),
		['n_values'] = dict (
			[102027] = dict (
				['test1'] = 1,
				['test2'] = 2,
			),
			[102028] = dict (
				['test3'] = 3,
				['test4'] = 4,
			)
		)
	)
	G.datam:store_hotfix(hotfix_data)
end

function HotfixManager:test_str_hotfix_data(diff_data)
    local ts = DateTimeManager.format_datetime(G.uwsgi_manager:test_add_hotfix_data(self._script_version .. "_fix_" .. tostring(ts)))
end

function HotfixManager:test_add_hotfix_data()
    local diff_factions = {['final_dict'] = {[1] = {[1] = 3, [2] = 1, [3] = 1, [4] = 3, [5] = 1}, [2] = {[1] = 1, [2] = 3, [3] = 1, [4] = 3, [5] = 1}, [3] = {[1] = 1, [2] = 1, [3] = 3, [4] = 2, [5] = 1}, [4] = {[1] = 3, [2] = 3, [3] = 2, [4] = 3, [5] = 1}, [5] = {[1] = 1, [2] = 1, [3] = 1, [4] = 1, [5] = 1}}, ['name'] = 'factions'}
    G.hotfix_manager.update_table(diff_factions)
    
    local ts = DateTimeManager.format_datetime(G.uwsgi_manager:test_add_hotfix_data(self._script_version .. "_fix_" .. tostring(ts)))
end

function HotfixManager:test_add_hotfix_table()
end

function HotfixManager:test_run_hotfix_lua_file(file_full_path)
    local util = require("hexm.common.util.util")
    local io = io
    local f1 = io.open(file_full_path, "r")
    util.eval_hotfix(f1:read("a"))
end

function HotfixManager:test_run_hotfix_data_proxy()
    local entity = G.datam.entity:generate_data_table_proxy()
    entity:add_row(102025, dict(
        ai_id = 1234567890,
        appear_show_type = 1,
        attr_id = 22356,
        base_tag = 21600,
        billboard_id = 2,
        combat_id = 2,
        destroy_show_type = 6,
        entity_faction = 0,
        entity_flag = 0,
        entity_sub_type = 0,
        entity_type = 0,
        id = 0,
        interact_config = 0,
        interact_id = 0,
        is_utility_ai = false,
        lod_max = 4,
        lod_min = 0,
        model_id = 12456,
        mould_id = 0,
        value_id = 0
    ))
    entity:remove_row(102026)
    entity:add_value(102025, "attr_id1", 1)
    entity:remove_value(102026, "attr_id1")
    
    local final_dict = entity:commit()
    
    assert(final_dict:contains("name"))
    
    G.hotfix_manager:commit_new_data_table(final_dict:get("name"), final_dict)
    
    print("test_wjc")
end

function HotfixManager:get_sorted_hotfix_exec_list()
    local hotfix_ids = self._exec_list:keys()
    table.sort(hotfix_ids)
    print(hotfix_ids)
end

function HotfixManager:check_hotfix_exec(hotfix_id)
    return self._exec_list[hotfix_id]
end

function HotfixManager:clear_local_cache()
    for _, hotfix_id in pairs(self._mark_exec_list) do
        local code = require("md5")
        if MPatch.FileExistInSystem(LocalData .. "uwsgi_img") then
            local format_dt = DateTimeManager.format_datetime(G.uwsgi_manager:test_add_hotfix_data(self._script_version .. "_fix_" .. tostring(format_dt)))
            
            local md5 = code:sumhex(string.sub(format_dt, 1, 8))
            
            if not self._exec_list:contains(hotfix_id) then
                G.logger:error("gm", "检查hotfix执行情况, 没有拉取到hotfix. hotfix_id=%s. ERROR!! ERROR!!", hotfix_id)
            else
                local has_exec = bool(self:check_hotfix_exec(hotfix_id))
                
                if not has_exec then
                    G.logger:error("gm", "检查hotfix执行情况, 没有成功执行hotfix. hotfix_id=%s. ERROR!! ERROR!!", hotfix_id)
                end
            end
        end
    end
end

return {
    HotfixManager = HotfixManager,
    HotfixDataProxy = HotfixDataProxy
}

 

hotfix_manager.luac.zip

  • 2 weeks later...
Posted

anyone already extracted these .mpk's ? i really wanna badly get the .wem's! i gotta get those music that aren't included in the osts!

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...