Jump to content

astroNOT

Premium
  • Posts

    48
  • Joined

  • Last visited

  • Days Won

    1
  • Feedback

    0%

Everything posted by astroNOT

  1. Ransomware just false positive i assume? Also ************** Exception Text ************** System.Exception: 0x33545844 texture compression not implemented. For this map [Hidden Content]
  2. There's no LLM atm that can "remember" as many tokens as a full game source requires, even gemini, it will only mean it has a long input stream, not that it remembers much of it, so we'll still have to wait Anyhow llms are definitelly good, for me gpts was the best at cpp for example
  3. Hello, here's a item list generator, for them lazy people (or with really tired eyes) Adds at eof, new item upgrades and respective location for icon/textures Req python 3.11 import re def generate_item_code(items): item_codes = [] for item in items: icon_location = item["icon_location"] texture_location = item["texture_location"] vnums = item["vnums"] for item_id in vnums: for i in range(10): item_code = f"{item_id + i}\tWEAPON\t{icon_location.replace('*', str(item_id))}\t{texture_location.replace('*', str(item_id))}" item_codes.append(item_code) return item_codes def write_to_txt(item_codes, file_path): with open(file_path, "r+") as file: existing_lines = file.readlines() for item_code in item_codes: if item_code + "\n" in existing_lines: item_vnum = re.split(r'\t+', item_code)[0] print(f"SKIPPED - Item code {item_vnum} already exists in item list") else: file.write(item_code + "\n") print(item_code) if __name__ == "__main__": # In order to use the locations params # If ur file requires any prefix "0*.tga", before * include ur prefix, also ur desired extension .tga in my case location_dict = [ { "icon_location": "icon/item/0*.tga", "texture_location": "d:/ymir work/item/weapon/0*.gr2", "vnums": [8190, 8290] } ] item_codes = generate_item_code(location_dict) txt_file_path = r"client_location\item_list.txt" write_to_txt(item_codes, txt_file_path)
  4. Can confirm that adding any instruction prior to while idle, seems to not give enough time for the maps & mobs to load try { // Hardcoded values const DWORD dwVnum = 101; const int count = 10; const bool isAggressive = false; const int iMapIndex = 352; const int iMapX = 360; const int iMapY = 360; // Assume SECTREE_MANAGER and CHARACTER_MANAGER are properly initialized and available PIXEL_POSITION pos; if (!SECTREE_MANAGER::instance().GetMapBasePositionByMapIndex(iMapIndex, pos)) { sys_log(0, "PPPPPPQQQ Error: Cannot find base position in this map %d", iMapIndex); } const CMob *pMonster = CMobManager::instance().Get(dwVnum); if (pMonster == NULL) { sys_log(0, "PPPPPPQQQ Error: No mob data for VNUM %d", dwVnum); } size_t SpawnCount = 0; for (size_t i = 0; i < count; ++i) { LPCHARACTER pSpawnMonster = CHARACTER_MANAGER::instance().SpawnMobRange( dwVnum, iMapIndex, pos.x - number(5, 5) + (iMapX * 100), pos.y - number(5, 5) + (iMapY * 100), pos.x + number(5, 5) + (iMapX * 100), pos.y + number(5, 5) + (iMapY * 100), false, pMonster->m_table.bType == CHAR_TYPE_MONSTER, isAggressive); if (pSpawnMonster != NULL) { SpawnCount++; } } sys_log(0, "Spawned %u monsters successfully.", SpawnCount); } catch (const std::exception &e) { sys_log(0, "An exception occurred: %s", e.what()); } while (idle()) ; What it logs is: ./srv1/chan/ch1/core1/syslog:Apr 17 19:23:11 :: PPPPPPQQQ Error: Cannot find base position in this map 352 ./srv1/chan/ch1/core1/syslog:Apr 17 19:23:11 :: PPPPPPQQQ Error: No mob data for VNUM 101 Trial and error continues
  5. Hello! Lets say I have the follow scenario: At server startup: I want to spawn two mobs, as an example function(correctness does not matter) void SpawnMobs(DWORD mob_vnum, int count, int map_index, int x, int y) { for (int i = 0; i < count; ++i) { LPCHARACTER mob = CHARACTER_MANAGER::instance().SpawnMob(mob_vnum, map_index, x, y, 0, false, -1); if (!mob) sys_err("Failed to spawn mob VNUM %d on map %d at (%d, %d)", mob_vnum, map_index, x, y); } } And at a given date-time, to make the mobs move to a specific location(Again function correctness is probably wrong, but this is just a POCE) void MoveMobTo(DWORD mob_vid, int target_x, int target_y) { using namespace std::chrono; //April 18, 2024, at 18:00 std::tm scheduled_time = {}; scheduled_time.tm_year = 2024 scheduled_time.tm_mon = 4 - 1; scheduled_time.tm_mday = 18; scheduled_time.tm_hour = 18; scheduled_time.tm_min = 0; scheduled_time.tm_sec = 0; auto scheduled_time_t = std::mktime(&scheduled_time); system_clock::time_point scheduled_tp = system_clock::from_time_t(scheduled_time_t); // Get current time system_clock::time_point now = system_clock::now(); // Check if the current time matches the scheduled time if (now == scheduled_tp) { LPCHARACTER mob = CHARACTER_MANAGER::instance().Find(mob_vid); if (mob) { mob->Goto(target_x, target_y); sys_log(0, "Mob with VID %d moved to (%d, %d) as scheduled", mob_vid, target_x, target_y); } else { sys_err("Failed to find mob with VID %d to move", mob_vid); } } else { sys_log(0, "MoveMobTo called, but it is not the scheduled time yet."); } } I have two main questions 1. !Where should i be calling these functions within the source game, in main seems like it might not be a good idea 2. Checking time constantly until desired time is true, seems quite tricky, a while true surely is not good, if u have any basic suggestions it would be more then welcomed Basically my goal is to have mobs spawn, if not already spawned, move them at a specific hour to a exact spot on the map, make em fight each other, while fighting pc can't attack, after pc can attack the surviver, but not instantly, spawn another boss, keep it there for a specific time, if not dead, despawn it Realistically, if i'd know where to call my functions with the instructions and how to not use while loops to check for specific states, it would be enough Thank you in advance!
  6. The idea is, i want this quest to run regardless of player actions, at the moment it seems to start at player login ideally the quest would start at day Y(could have daily flag) hour X so basically a scheduler, so it won't be dependent on any player events quest test_npcmove begin state start begin when letter begin chat("Started") set_state("spawn_monster_in_map_boss_1") end end -- State to check for/spawn boss 1 state spawn_monster_in_map_boss_1 begin when letter begin chat("Spawning first boss") local mob_vnum = 102 -- Adjust VNUM for boss 1 local map_index = 352 local mobs = find_mobs_in_map(mob_vnum, map_index) local vid_boss1 = 0 local mobs_str = "BOSS 1 VIDs: {" .. table.concat(mobs, ", ") .. "}" chat(mobs_str) chat("Player X: " .. 339 .. " Y: " .. 363) if table.getn(mobs) > 0 then vid_boss1 = mobs[1] chat("Boss 1 found, using existing with VID: " .. tostring(vid_boss1)) else local vids = spawn_monster_in_map(mob_vnum, 1, false, map_index, 339, 363 + 10, true) vid_boss1 = vids[1] if vids[1] ~= nil then vid_boss1 = vids[1] chat("Boss 1 spawned with VID: " .. tostring(vid_boss1)) else vids = find_mobs_in_map(mob_vnum, map_index) vid_boss1 = vids[1] chat("Boss 2 fetched vid for spwaned mob: " .. tostring(vid_boss1)) end end pc.setqf("vid_boss1", vid_boss1) set_state("spawn_monster_in_map_boss_2") end end -- State to check for/spawn boss 2 state spawn_monster_in_map_boss_2 begin when letter begin local mob_vnum = 101 -- Adjust VNUM for boss 2 local map_index = 352 local mobs = find_mobs_in_map(mob_vnum, map_index) local vid_boss2 = 0 local mobs_str = "BOSS 2 VIDs: {" .. table.concat(mobs, ", ") .. "}" chat(mobs_str) if table.getn(mobs) > 0 then vid_boss2 = mobs[1] chat("Boss 2 found, using existing with VID: " .. tostring(vid_boss2)) else local vids = spawn_monster_in_map(mob_vnum, 1, false, map_index, 339, 363 - 10, true) vid_boss2 = vids[1] if vids[1] ~= nil then vid_boss2 = vids[1] chat("Boss 1 spawned with VID: " .. tostring(vid_boss2)) else vids = find_mobs_in_map(mob_vnum, map_index) vid_boss2 = vids[1] chat("Boss 2 fetched vid for spwaned mob: " .. tostring(vid_boss2)) end end pc.setqf("vid_boss2", vid_boss2) set_state("move_bosses") end end -- State to move both bosses state move_bosses begin when letter begin local vid_boss1 = pc.getqf("vid_boss1") local vid_boss2 = pc.getqf("vid_boss2") local target_x = 339 local target_y = 363 mob_move(vid_boss1, target_x, target_y) mob_move(vid_boss2, target_x, target_y) chat("Both bosses moved to player's position.") set_state("bosses_fight") end end -- State where bosses fight state bosses_fight begin when letter begin local vid_boss1 = pc.getqf("vid_boss1") local vid_boss2 = pc.getqf("vid_boss2") local map_index = 352 chat("Boss 1 VID: " .. tostring(vid_boss1)) chat("Boss 2 VID: " .. tostring(vid_boss2)) local success2, message2 = set_pc_can_attack_monster(vid_boss1, false, map_index) local success3, message3 = set_pc_can_attack_monster(vid_boss2, false, map_index) chat("Attempt to make boss 1 invinciple " .. tostring(success2) .. " - " .. message2) chat("Attempt to make boss 2 invinciple " .. tostring(success3) .. " - " .. message3) -- Attempt to make boss 1 attack boss 2 local success1, message1 = attack_mob(vid_boss1, vid_boss2, map_index) if success1 ~= nil and message1 ~= nil then chat("Attack attempt from Boss 1 to Boss 2: " .. tostring(success1) .. " - " .. message1) else chat("Attack attempt from Boss 1 to Boss 2: success or message is nil") end -- Attempt to make boss 2 attack boss 1 local success2, message2 = attack_mob(vid_boss2, vid_boss1, map_index) if success2 ~= nil and message2 ~= nil then chat("Attack attempt from Boss 2 to Boss 1: " .. tostring(success2) .. " - " .. message2) else chat("Attack attempt from Boss 2 to Boss 1: success or message is nil") end chat("Bosses are now set to fight each other.") chat("---------------------------------END------------------------------------") set_state("bosses_alive") end end state bosses_alive begin when letter begin chat("Checking if boss died") local vid_boss1 = pc.getqf("vid_boss1") local vid_boss2 = pc.getqf("vid_boss2") local map_index = 352 -- Check if Boss 1 is alive local is_boss1_alive, boss1_msg = is_mob_alive_in_map(vid_boss1, map_index) chat("Boss 1 alive check: " .. tostring(is_boss1_alive) .. " - " .. boss1_msg) -- Check if Boss 2 is alive local is_boss2_alive, boss2_msg = is_mob_alive_in_map(vid_boss2, map_index) chat("Boss 2 alive check: " .. tostring(is_boss2_alive) .. " - " .. boss2_msg) -- Determine the next state based on the bosses' statuses if not is_boss1_alive or not is_boss2_alive then if is_mob_alive_in_map(vid_boss1, map_index) then local success2, message2 = set_pc_can_attack_monster(vid_boss1, true, map_index) chat("Resetting invicibility for boss1 " .. tostring(success2) .. " - " .. message2) end if is_mob_alive_in_map(vid_boss2, map_index) then local success3, message3 = set_pc_can_attack_monster(vid_boss2, true, map_index) chat("Resetting invicibility for boss2 " .. tostring(success3) .. " - " .. message3) end chat("One of the bosses is dead. Resetting quest.") set_state("start") else chat("Both bosses are alive. Continuing the fight.") set_state("bosses_alive") end end end end And the last state, called bosses_alive seems to also reexecute only at player relog (login) Is there a way to make it so the states are independent of player events and just execute as soon as sv starts?
  7. Hello, So I m trying to find where this vnum.kill function is defined on serverside, seems quite tricky, if anybody knows where it is defined and what name it has, please lmk Thanks, Gabi might be this guy void CQuestManager::Kill(unsigned int pc, unsigned int npc) { //m_CurrentNPCRace = npc; PC * pPC; sys_log(0, "CQuestManager::Kill QUEST_KILL_EVENT (pc=%d, npc=%d)", pc, npc); if ((pPC = GetPC(pc))) { if (!CheckQuestLoaded(pPC)) return; // kill call script if (npc >= MAIN_RACE_MAX_NUM) //@fixme109 m_mapNPC[npc].OnKill(*pPC); //@warme004 m_mapNPC[QUEST_NO_NPC].OnKill(*pPC); #ifdef ENABLE_PARTYKILL // party_kill call script LPCHARACTER ch = GetCurrentCharacterPtr(); LPPARTY pParty = ch->GetParty(); LPCHARACTER leader = pParty ? pParty->GetLeaderCharacter() : ch; if (leader) { m_pCurrentPartyMember = ch; if (npc >= MAIN_RACE_MAX_NUM) //@fixme109 m_mapNPC[npc].OnPartyKill(*GetPC(leader->GetPlayerID())); //@warme004 m_mapNPC[QUEST_NO_NPC].OnPartyKill(*GetPC(leader->GetPlayerID())); pPC = GetPC(pc); } #endif } else sys_err("QUEST: no such pc id : %d", pc); }
  8. ALUA(_spawn_monster_in_map) { if (false == lua_isnumber(L, 1) || false == lua_isnumber(L, 2) || false == lua_isboolean(L, 3) || false == lua_isnumber(L, 4) || false == lua_isnumber(L, 5) || false == lua_isnumber(L, 6)) { lua_pushnumber(L, 0); // Return an error in the form of 0 if inputs are incorrect return 1; } const DWORD dwVnum = static_cast<DWORD>(lua_tonumber(L, 1)); const size_t count = MINMAX(1, static_cast<size_t>(lua_tonumber(L, 2)), 10); const bool isAggressive = static_cast<bool>(lua_toboolean(L, 3)); const int iMapIndex = static_cast<int>(lua_tonumber(L, 4)); const int iMapX = static_cast<int>(lua_tonumber(L, 5)); const int iMapY = static_cast<int>(lua_tonumber(L, 6)); PIXEL_POSITION pos; if (!SECTREE_MANAGER::instance().GetMapBasePositionByMapIndex(iMapIndex, pos)) { sys_err("QUEST _spawn_mob_in_map: cannot find base position in this map %d", iMapIndex); lua_pushnumber(L, 0); // Push 0 to indicate failure return 1; } const CMob *pMonster = CMobManager::instance().Get(dwVnum); if (pMonster == NULL) { sys_err("QUEST _spawn_mob_in_map: no mob data for VNUM %d", dwVnum); lua_pushnumber(L, 0); // Push 0 to indicate failure return 1; } lua_newtable(L); // Create a new table on the stack to hold the VIDs size_t SpawnCount = 0; for (size_t i = 0; i < count; ++i) { LPCHARACTER pSpawnMonster = CHARACTER_MANAGER::instance().SpawnMobRange(dwVnum, iMapIndex, pos.x - number(200, 750) + (iMapX * 100), pos.y - number(200, 750) + (iMapY * 100), pos.x + number(200, 750) + (iMapX * 100), pos.y + number(200, 750) + (iMapY * 100), true, pMonster->m_table.bType == CHAR_TYPE_MONSTER, isAggressive); if (pSpawnMonster != NULL) { lua_pushnumber(L, SpawnCount + 1); // Push the index in the table lua_pushnumber(L, pSpawnMonster->GetVID()); // Push the VID lua_settable(L, -3); // Set the table at index -3 with key at -2 and value at -1 SpawnCount++; } } sys_log(0, "QUEST Spawn Monster: VNUM(%u) COUNT(%u) isAggressive(%b)", dwVnum, SpawnCount, isAggressive); return 1; // Returns the table at the top of the stack } As u can see above i spawn the mob as `CHAR_TYPE_MONSTER` but when I m checking if if (attacker->IsNPC() || target->IsNPC()) { sys_log(0, "MOB_ATTACK_FUNC Victim is NPC not Monster not attackable"); lua_pushboolean(L, 0); lua_pushstring(L, "MOB_ATTACK_FUNC Victim is NPC not Monster not attackable"); return 0; } This is always returning true, and bcs of it, i cannot set `bool bAttackSuccess1 = attacker->Attack(target, 0);` Because apparently a npc cannot attack does anybody know how to spawn a mob (Character instance) that is not NPC but mosnter so it can attack other monsters?
  9. I m trying to make a mob, attack another mob, by specific attacker vid and victim vid, but can't figure out which Character class method does the actual attack int game_mob_attack_mob(lua_State *L) { if (!lua_isnumber(L, 1) || !lua_isnumber(L, 2) || !lua_isnumber(L, 3)) { lua_pushboolean(L, 0); lua_pushstring(L, "Invalid argument. Usage: mob_attack_mob(attacker_vid, target_vid, map_index)"); return 2; } int attacker_vid = (int)lua_tonumber(L, 1); int target_vid = (int)lua_tonumber(L, 2); int map_index = (int)lua_tonumber(L, 3); // Expected map index LPCHARACTER attacker = CHARACTER_MANAGER::instance().Find(attacker_vid); LPCHARACTER target = CHARACTER_MANAGER::instance().Find(target_vid); if (!attacker || !attacker->IsMonster()) { lua_pushboolean(L, 0); lua_pushstring(L, "Attacker not found or is not a monster."); return 2; } if (!target || !target->IsMonster()) { lua_pushboolean(L, 0); lua_pushstring(L, "Target not found or is not a monster."); return 2; } if (attacker->GetMapIndex() != map_index || target->GetMapIndex() != map_index) { lua_pushboolean(L, 0); lua_pushstring(L, "Either attacker or target is not in the specified map."); return 2; } // All checks passed, proceed to set victim attacker->SetVictim(target); attacker->BeginFight(target); lua_pushboolean(L, 1); lua_pushstring(L, "Attack set successfully."); return 2; } Basically, "Attack set successfully is triggered but the mobs do not attack each otther, even if they are loading by their vid... Updated it to use attacker->SetVictim(target); target->SetVictim(attacker); // Trigger the initial attack and capture the return values bool bAttackSuccess1 = attacker->Attack(target, 0); // Return the result of the first attack attempt to Lua for debugging lua_pushboolean(L, bAttackSuccess1); if (bAttackSuccess1) lua_pushstring(L, "Attack by attacker was successful."); else lua_pushstring(L, "Attack by attacker failed."); return 2; } But for some reason Attack method does not get triggered at all.. but the Attack by attacker failed is pushed succesfully
  10. Thanks @ Ikarus_ and @ HFWhite for both of ur help, you have been very helpful and really solved such a headache that this was causing for me
  11. Dosen't seem like anything special, just 3 classes from initial implementation of ui.py that had to be added CheckBox, ExpandedButton and CustomScrollBar that I just had to copy pasted. But it seems like most actions are defined here, so in terms of accuracy for ui part ur spot on, i expect on launcher side that I might have some problems, even tho i did double check a couple of times and it seems like i p much moved everything where it should be.. Thank you tho, I'll keep looking
  12. So Back in 2021, i bought @ Ikarus_'s shop offline, as most ppl know, V1 of the shop is not supported by ikarus anymore, so I am on my own out here hahaha The idea is back in 2021 I wanted to open a server, long story short svf was compromised and couldn't go further with the idea Now, i bought marty's svf, and I want to transfer the shop from my old server to this one But i hit a dead end with debugging, can't figure out how a click event is handle The problem is: So problem seems to be that from uinewofflineshop.py, NewOfflineShopBoard.__OnLeftClickShopItem method is not called at all when i click on a item that is already in a shop, and i now do not know what to look for to understand how it works, what function/class handles the mouse over stuff and triggers specific events when an item is clicked, basically to understand how __OnLeftClickShopItem is triggered and when. There is a method NewOfflineShopBoard.RefreshOpenShopPage that is triggered and sets this "mouse up" event slot.SetOnMouseLeftButtonUpEvent(self.__OnLeftClickShopItem) But for some reason it aint working, not sure where to go from here realistically
  13. Hi guys, in which file on launcher C++ side do i need to declare a variable/object for it to be visible and so I can import it in client pack .py files?
  14. import os #no of channels channels = 4 #no of cores cores = 2 #Channels path chan_location = "/usr/home/main/srv1/chan/" #New ip to replace the old ip_value = "123.443.9.1" try: os.mkdir("%sbackup_config" % chan_location) except Exception: pass for i in range(1, channels + 1): # print(i) for core in range(1, cores + 1): with open(f"%sch{i}/core{core}/CONFIG" % chan_location, 'r') as cfg: count = 0 proxy_index = 0 list_of_lines = cfg.readlines() with open(f"%sbackup_config/config_channel{i}_core{core}" % chan_location, "w") as bk_file: bk_file.writelines(list_of_lines) for line in list_of_lines: count += 1 # print(line) if "proxy" in line.lower(): proxy_index = count - 1 # print(len(list_of_lines), 'list of lines len') print("proxy index ", proxy_index) list_of_lines[proxy_index] = "proxy_ip: %s\n" % ip_value with open(f"%sch{i}/core{core}/CONFIG" % chan_location, 'w') as cfg_w: cfg_w.writelines(list_of_lines) print(f"Succesfully updated config for Channel{i}, Core{core}")
  15. Indeed it removes the last char, in our chase the /n, aaand if its the last line in the file w/o a nl, then its doomed, updated the topic accordingly, thanks!
  16. Hello, When adding the bellow string to locale_game.txt APPLY_ANTI_RESIST_MAGIC Magic Pen: %d%% SA A key error is raised: 0613 21:44:08342 :: system.py(line:287) RunMainScript system.py(line:204) execfile prototype.py(line:3) <module> system.py(line:151) __hybrid_import system.py(line:116) _process_result localeInfo.py(line:210) <module> localeInfo.py(line:167) LoadLocaleFile Run - <type 'exceptions.KeyError'>:'S' 0613 21:44:08343 :: ============================================================================================================ 0613 21:44:08343 :: Abort!!!! Without the SA at the end, the bonus name is not properly displayed in game W/o the SA at the end, the bonus name is displayed as "UNKNOWN_NAME(93), the 93 is the index for the bonus in `enum EApplyTypes` from itemData.h Any ideas? LoadLocalFile py function: Thanks! EDIT: SOLVED: Because of this stupid line of code `tokens = line[:-1].split("\t")` you gotta have an extra char(space/new line) after 'SA' *only if its the last line in the file*
  17. M2 Download Center Download Here ( Internal ) The script updates item prices (buy/sell) for an item vnum: Considering item vnum is 110, it can update till 119 (or starting vnum 112 can go till 115, or 117, or w/e you desire) It can update for a single vnum (upgrade items, aswell), more in comments below Combined with can be pretty efficient from halo import Halo import bcolors class Append_new_prices: def __init__(self, value_dict, proto_location): self.proto_location = proto_location self.protoLst = [] self.value_dict = value_dict def get_proto_asList(self): with open(self.proto_location, 'r', encoding="utf8") as file: for line in file.readlines(): lineLst = line.split('\t') self.protoLst.append(lineLst) self.modified_protoLst = [] def update_protoLst(self): count = 0 for vnum, prices in self.value_dict.items(): try: upp_range = prices['uppLimit'] except KeyError: upp_range = 1 vnum_lst = self.get_item_VnumRange(vnum, upp_range) # while upp_range >= 0: for lineLst in self.protoLst: if "buy" not in prices.keys(): prices['buy'] = 0 if "sell" not in prices.keys(): prices['sell'] = 0 # print((lineLst[0]), " == ", vnum_lst) try: line_vnum = int(lineLst[0]) except ValueError: line_vnum = "VNUM NOT INT PFFFFF" if line_vnum in vnum_lst: lineLst[9] = prices['buy'] lineLst[10] = prices['sell'] self.protoLst[self.protoLst.index(lineLst)] = lineLst @staticmethod def get_item_VnumRange(vnum, range_lim): vnum_lst = [] plus_val = 0 # if range_lim == 0: # range_lim = 1 vnum = int(vnum) for i in range(0, range_lim + 1): vnum += plus_val vnum_lst.append(vnum) plus_val = 1 return vnum_lst def write_new_proto_fromList(self): with open(self.proto_location, 'w', encoding="utf8") as file: for line in self.protoLst: file.write('\t'.join(self.str_list(line))) def str_list(self, lst): new_lst = [] for i in lst: new_lst.append(str(i)) return new_lst if __name__ == "__main__": #First number (110) is the starting vnum, uppLimit is till when to stop adding prices, upplimit 9 means => 110, 111, 112, 113, 114...119 #It can have h/e many "item" objects as dictionary elements #!!!!!Count starts from 0! items = \ { "110": { "buy": 55, "sell": 43, "uppLimit": 1 }, # "120":{ # "buy":4000, # "sell":400000, # "uppLimit":9 # } } setPrices = Append_new_prices(value_dict=items, proto_location=r'C:\Users\itsas\Desktop\M2\versionControl\DumpProto\Release\item_proto.txt') with Halo(text='Loading', spinner='dots'): setPrices.get_proto_asList() setPrices.update_protoLst() setPrices.write_new_proto_fromList() print(f'{bcolors.OKMSG}{bcolors.OK} Done!') Prereq: Libs: Halo, bcoloros Python 3.9
  18. M2 Download Center Download Here ( Internal ) Hello peeps! Got some more utilities that i use to automate boring stuff, so, maybe it can help u guys too The script kills the client processes, generates dump_proto and moves it into locale_xx directory (optional), crypts a list of files(root, locale, icon, ...etc) and starts the client. import os import shutil import bcolors import time class utilities: def __init__(self, packer_path, client_path, launcher_Name, dumpProto_path, locale_XX_path): self.packer_path = packer_path self.client_path = client_path self.launcher_Name = launcher_Name self.dumpProto_path = dumpProto_path self.locale_XX_path = locale_XX_path def fox_Pack(self, filesList): for i in filesList: print(f"\t* Will exec :> [{i}]") os.chdir(self.packer_path) os.system(f"tools\\Archiver.exe make_xml/{i}_create.xml") os.system(f"tools\\Archiver.exe xml/{i}_create.xml") time.sleep(0.5) # os.system(archiver_path) def killProcess(self): import psutil for proc in psutil.process_iter(): # check whether the process name matches if proc.name() == self.launcher_Name: proc.kill() time.sleep(0.5) def createItemProto(self): os.chdir(self.dumpProto_path) os.system(f"{self.dumpProto_path}\\dump_proto.exe") if os.path.isfile(self.locale_XX_path + r"\item_proto_old"): os.remove(self.locale_XX_path + r"\item_proto_old") os.rename(self.locale_XX_path + "\\item_proto", self.locale_XX_path + "\\item_proto_old") shutil.copy2("item_proto", self.locale_XX_path) def startClient(self): os.chdir(self.client_path) os.startfile(self.client_path + "\\" + self.launcher_Name) if __name__ == "__main__": start_time = time.time() print(f"{bcolors.OKMSG}{bcolors.OK}#-------[START]-------#\n{bcolors.ENDC}") utils = utilities( #packer Location packer_path = r"C:\Users\itsas\Desktop\M2\versionControl\client\Packer", #client Location client_path = r"C:\Users\itsas\Desktop\M2\versionControl\client\Metin2", launcher_Name = "metin2_launcher.exe", #dumpProto RELEASE Location dumpProto_path = r"C:\Users\itsas\Desktop\M2\versionControl\DumpProto\Release", #locale\XX Location locale_XX_path = r"C:\Users\itsas\Desktop\M2\versionControl\client\Client\locale_general\ro") utils.killProcess() utils.createItemProto() #To pack multiple files, addd in the below list more, directory names utils.fox_Pack(["locale_general", "icon", "item"]) utils.startClient() print(f"{bcolors.BLUE}--- {bcolors.WAITMSG}{bcolors.BLUE}{(time.time() - start_time)} seconds ---\n{bcolors.ENDC}") print(f"{bcolors.OKMSG}{bcolors.OK}#-------[STOP]-------#") Prereq: Python 3.9 Libraries: bcolors, shutil
  19. Hello, Some boring clicking automated that I use, feel free to improve it, add waits, w/e, w/e import time, os from pywinauto import Desktop, Application import bcolors from pywinauto.keyboard import send_keys import psutil class mySession: app = Application(backend='uia') def __init__(self, vm_Name='', ssh_Name='', cliente_exe_Path='', winSCP_path='', vbox_exe_path=''): self.vm_Name = vm_Name self.ssh_Name = ssh_Name self.cliente_exe_Path = cliente_exe_Path pathList = cliente_exe_Path.split('\\') self.client_path = '/'.join(pathList[:-1]) self.exe_name = pathList[-1] self.vbox_exe_path = vbox_exe_path self.winSCP_path = winSCP_path def openVM(self, waitServer): self.killProcess("VirtualBox.exe") self.app.start(self.vbox_exe_path) self.app = Application(backend='uia').connect(title='Oracle VM VirtualBox Manager', timeout=10) # self.app.Dialog.print_control_identifiers() self.app.OracleVMVirtualBoxManager.child_window(title=self.vm_Name, control_type="ListItem").wrapper_object().click_input(button='left', double=True) # self.app = Application(backend='uia').connect(title=self.whoAmI('Starting')[0], timeout=10) time.sleep(waitServer) print(f"\t{bcolors.OK}{bcolors.OKMSG}VM is ready{bcolors.ENDC}") def openWinSCP(self): self.killProcess("WinSCP.exe") self.app.start(self.winSCP_path) self.app = Application(backend='uia').connect(title=self.whoAmI(keyword='wins')[0], timeout=40) time.sleep(1) if self.app.Dialog.child_window(title=self.ssh_Name + " ", control_type="TabItem").exists(): self.app.Dialog.child_window(title="Reconnect Session", control_type="Button").wrapper_object().click_input( button='left') else: self.app.Dialog.child_window(title="New Session", control_type="TabItem").wrapper_object().click_input(button='left') auth_win = self.app.Dialog.child_window(title=self.ssh_Name, control_type="TreeItem") auth_win.wait('visible', timeout=50) auth_win.wrapper_object().click_input(button='left', double=True) input_pass = self.app.Dialog.child_window(control_type="Edit") input_pass.wait('visible', timeout=50) input_pass.wrapper_object().type_keys("dev") self.app.Dialog.child_window(title="OK", control_type="Button").wrapper_object().click_input(button='left') time.sleep(2) print(f"\t{bcolors.OK}{bcolors.OKMSG}WinScp is ready{bcolors.ENDC}") def startClient(self, do_login=True): os.chdir(self.client_path) os.startfile(self.client_path + "\\" + self.exe_name) # self.app = Application(backend='uia').connect(title='Metin2', timeout=10) def whoAmI(self, keyword='', retryLimit=2, isFull=False): while retryLimit: windows = Desktop(backend="uia").windows() windowsList = [w.window_text() for w in windows] resultList = [] for i in windowsList: if keyword.lower() in i.lower(): resultList.append(i) if not len(resultList): time.sleep(0.5) self.whoAmI(keyword=keyword, retryLimit=retryLimit-1, isFull=isFull) else: # print('Matches: ', resultList) if not isFull: return resultList else: return windowsList def killProcess(self, proc_nmame, kill_=True): if kill_: for proc in psutil.process_iter(): # check whether the process name matches if proc.name() == proc_nmame: proc.kill() time.sleep(0.5) if __name__ == "__main__": print(f"{bcolors.OK}#########[START]#########{bcolors.ENDC}") #Here you have to give the name of ur Virtual Machine(vm_Name), winSCP ssh connetion name(ssh_Name), and ur client executable path controller = mySession(vm_Name="11.3_5.5_v4", ssh_Name="alpha_server", cliente_exe_Path=r"C:\Users\itsas\Desktop\M2\versionControl\client\Metin2\metin2_launcher.exe", vbox_exe_path='"C:\Program Files\Oracle\VirtualBox\VirtualBox.exe"', winSCP_path="C:\Program Files (x86)\WinSCP\WinSCP.exe") controller.openVM(waitServer=15) controller.openWinSCP() controller.startClient() print(f"{bcolors.OK}#########[END]#########{bcolors.ENDC}") Prereq: Python 3.9 Libs: pywinauto, psutil, bcolors Note: The script does kill existing processes of WinSCP and oracle VM, you can disable it, if u feel the need, search for killProcess method and set default param to False Edit: Parametrized paths for vbox, winSCP also
  20. Indeed it worked, with a slight catch.. What i had 2 to do is to add more height to all the parent elements, starting from the first parent, and following the nesting Thank you!
  21. Hello, I have this 1 button which is not clickable in the following position: Faulty position: [Hidden Content] But if i move it higher it works just fine, I not sure what to do, any ideas would be appreciated Working position: [Hidden Content] The actual ui dictionary:
  22. Hello, I'm keen to know, is there a way to increase a specific item texture specular (weapon/armor/etc) beyond the 100 that you can set in specular column? Or better yet to edit the texture to define what 100 specular should be. Point is, some items aren't as shiny as they should be at 100 specular PS. I assume the specular is tied to the texture. Thanks!
  23. Any chance u got the set for all characters?
×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.