-
Posts
35 -
Joined
-
Last visited
-
Feedback
0%
About Werwolf94

- Birthday 08/30/1994
Informations
-
Gender
Male
-
Country
Hungary
-
Nationality
Hungarian
Recent Profile Visitors
The recent visitors block is disabled and is not being shown to other users.
Werwolf94's Achievements
-
Werwolf94 started following npc arrow , GF-Like Inventory Slot Marking System , Proto Converter | XML 2 SQL | SQL 2 TXT and 7 others
-
official GF-Like Inventory Slot Marking System
Werwolf94 replied to xP3NG3Rx's topic in Features & Metin2 Systems
If you only copy-paste the codes from the tutorial could it cause syserr's like these? 0104 20:39:37401 :: Phase Game does not handle this header (header: 81, last: 45, 81) 0104 20:39:37416 :: Unknown packet header: 102, last: 45 81 0104 20:39:37434 :: Unknown packet header: 102, last: 45 81 0104 20:39:37449 :: Unknown packet header: 102, last: 45 81 [... endlessly repeating this ...] Or: 1218 22:33:34356 :: Phase Game does not handle this header (header: 81, last: 45, 81) 1218 22:33:34389 :: Unknown packet header: 101, last: 45 81 1218 22:33:34405 :: Unknown packet header: 101, last: 45 81 1218 22:33:34422 :: Unknown packet header: 101, last: 45 81 [... endlessly repeating this ...] After teleporting the character stays half-transparent, you couldn't interact with anything (like when your internet connection is interrupted), but the server receives packets from the client anyway, so if I use my self-buff skills in a warrior character the client stays in this frozen state, the effect like Aura of the sword don't applied to my sword client side, but it's registered in server side, i saw in the LOG-s, serverside there is not any syserr at all. Maybe the cause is this line at the tutorial PythonNetworkStreamPhaseGame.cpp part: CPythonExchange::Instance().SetItemToTarget(iSlotIndex, exchange_packet.arg1, (WORD)exchange_packet.arg3); I compared the files to the original source and I saw it should look like this (space between the (WORD) and the exchange_packet.arg3): CPythonExchange::Instance().SetItemToTarget(iSlotIndex, exchange_packet.arg1, (WORD) exchange_packet.arg3); Or maybe the disabled _IMPROVED_PACKET_ENCRYPTION_ could cause errors like this? Typically happens at Wi-Fi network, never at LAN connection. I saw someone else has similar problem like mine: [Hidden Content] Any suggestion is welcomed! -
The root of your problem is newer Python2.7 versions doesn't support some operators which in older versions where accepted. I faced the same problem as you, if you want to use this cool script in 2025, I use FreeBSD 13.4 release. You need to downgrade your Python first. Secondly py-MySQLdb isn't at your ports collection anymore. So if you installed your server for example from TMP4 guide You was forced to install packages with pkg add (pkg add -f to be exact because force install is needed!) command because for example MySQL 5.6 server cannot be found at FreeBSD 13.4's ports collection. TMP4's package backup 64 folder contains Python2.7: python27-2.7.18_2 version You need an older one because scripts like this: def get_flag(flag): if flag == "": return flag else: return "\"" + flag + "\"" Causing: TypeError: cannot concatenate 'str' and 'set' objects Errors when you run this cool serverside DB to TXT script. Uninstalling python27-2.7.18_2, installing python27-2.7.11_1 garbaged from FreeBSD 10.3 solved my problem. I share with you my package backup files which you can install in your newer FreeBSD system: [Hidden Content] The tar file readme instructions file is wrong (/usr/pkg_backup_amd64/ is missing from the pkg add -f commands), please follow these: Older Python2.7 amd py-MySQLdb extension for higher version FreeBSD's. -Copy this folder (pkg_backup_amd64) to your /usr folder. -Uninstall your newer Python2.7 software if needed: pkg remove python27 -Force install these with this commands to your FreeBSD's console: pkg add -f /usr/pkg_backup_amd64/python27-2.7.11_1.txz pkg add -f /usr/pkg_backup_amd64/py27-setuptools27-19.2.txz pkg add -f /usr/pkg_backup_amd64/python2-2_3.txz pkg add -f /usr/pkg_backup_amd64/py27-MySQLdb-1.2.5.txz Now if you run: python2.7 convert_test.py hopefully it will run smoothly without errors! Enjoy your working DB -> TXT converter! Oh, and a small script for the converter, you noticed that fact of Wild dog and Yang text is missing from your client? That's because it's the first row in your protos, open your db->txt.py find this: print "Converting mob_proto..." Add under: mob_proto_line1 = "VNUM NAME RANK TYPE BATTLE_TYPE LEVEL SIZE AI_FLAG MOUNT_CAPACITY SETRACEFLAG SETIMMUNEFLAG EMPIRE FOLDER ON_CLICK ST DX HT IQ DAMAGE_MIN DAMAGE_MAX MAX_HP REGEN_CYCLE REGEN_PERCENT GOLD_MIN GOLD_MAX EXP DEF ATTACK_SPEED MOVE_SPEED AGGRESSIVE_HP_PCT AGGRESSIVE_SIGHT ATTACK_RANGE DROP_ITEM RESURRECTION_VNUM ENCHANT_CURSE ENCHANT_SLOW ENCHANT_POISON ENCHANT_STUN ENCHANT_CRITICAL ENCHANT_PENETRATE RESIST_SWORD RESIST_TWOHAND RESIST_DAGGER RESIST_BELL RESIST_FAN RESIST_BOW RESIST_FIRE RESIST_ELECT RESIST_MAGIC RESIST_WIND RESIST_POISON DAM_MULTIPLY SUMMON DRAIN_SP MOB_COLOR POLYMORPH_ITEM SKILL_LEVEL0 SKILL_VNUM0 SKILL_LEVEL1 SKILL_VNUM1 SKILL_LEVEL2 SKILL_VNUM2 SKILL_LEVEL3 SKILL_VNUM3 SKILL_LEVEL4 SKILL_VNUM4 SP_BERSERK SP_STONESKIN SP_GODSPEED SP_DEATHBLOW SP_REVIVE" out_file_mobproto.write(mob_proto_line1 + "\r\n") mob_names_line1 = "VNUM LOCALE_NAME" out_file_mobnames.write(mob_names_line1 + "\r\n") Find this: print "Converting item_proto..." Add under: item_proto_line1 = "VNUM NAME TYPE SUBTYPE SIZE ANTIFLAG FLAG WEARFLAG IMMUNEFLAG GOLD SHOP_BUY_PRICE REFINED_VNUM REFINE_SET MAGIC_PCT LIMITTYPE0 LIMITVALUE0 LIMITTYPE1 LIMITVALUE1 APPLYTYPE0 APPLYVALUE0 APPLYTYPE1 APPLYVALUE1 APPLYTYPE2 APPLYVALUE2 VALUE0 VALUE1 VALUE2 VALUE3 VALUE4 VALUE5 SPECULAR SOCKET_PCT ADDON_TYPE" out_file_itemproto.write(item_proto_line1 + "\r\n") item_names_line1 = "VNUM LOCALE_NAME" out_file_itemnames.write(item_names_line1 + "\r\n") So the first line skip problem will be fixed with this modification. Also, there is a # mark at the end of the file which could prevent your mob_proto.txt files to be compiled. Here is my full converter py file: #!/usr/bin/env python #-*- coding" utf-8 -*- #Modified by Deucalion import MySQLdb host_mysql = 'localhost' user_mysql = 'root' passwd_mysql = '' def mob_proto(): rank = { 1: "S_PAWN", 2: "KNIGHT", 3: "S_KNIGHT", 4: "BOSS", 5: "KING", } typeee = { 1: "NPC", 2: "STONE", 3: "WARP", 4: "DOOR", 5: "BUILDING", 7: "POLYMORPH_PC", 8: "HORSE", 9: "GOTO", } battletype = { 2: "RANGE", 3: "MAGIC", 4: "SPECIAL", 5: "POWER", 6: "TANKER", } def get_rank(level): if level in rank: return "\"" + rank[level] + "\"" else: return "\"PAWN\"" def get_type(typee): if typee in typeee: return "\"" + typeee[typee] + "\"" else: return "\"MONSTER\"" def get_battletype(battle): if battle in battletype: return "\"" + battletype[battle] + "\"" else: return "\"MELEE\"" def get_flag(flag): if flag == "": return flag else: return "\"" + flag + "\"" def get_race(race): if race == "": return race else: return "\"" + race + "\"" def get_immune(immune): if immune == "": return immune else: return "\"" + immune + "\"" def get_folder(folder): if folder == "": return "\"wolf\"" else: return "\"" + folder + "\"" print "Connecting to database proto..." data = "player" db = MySQLdb.connect(host_mysql,user_mysql,passwd_mysql,data) cur = db.cursor() print "Connected." cur.execute("select * from mob_proto") rows = cur.fetchall() out_file_mobproto = open("mob_proto.txt", "w") out_file_mobnames = open("mob_names.txt", "w") print "Converting mob_proto..." mob_proto_line1 = "VNUM NAME RANK TYPE BATTLE_TYPE LEVEL SIZE AI_FLAG MOUNT_CAPACITY SETRACEFLAG SETIMMUNEFLAG EMPIRE FOLDER ON_CLICK ST DX HT IQ DAMAGE_MIN DAMAGE_MAX MAX_HP REGEN_CYCLE REGEN_PERCENT GOLD_MIN GOLD_MAX EXP DEF ATTACK_SPEED MOVE_SPEED AGGRESSIVE_HP_PCT AGGRESSIVE_SIGHT ATTACK_RANGE DROP_ITEM RESURRECTION_VNUM ENCHANT_CURSE ENCHANT_SLOW ENCHANT_POISON ENCHANT_STUN ENCHANT_CRITICAL ENCHANT_PENETRATE RESIST_SWORD RESIST_TWOHAND RESIST_DAGGER RESIST_BELL RESIST_FAN RESIST_BOW RESIST_FIRE RESIST_ELECT RESIST_MAGIC RESIST_WIND RESIST_POISON DAM_MULTIPLY SUMMON DRAIN_SP MOB_COLOR POLYMORPH_ITEM SKILL_LEVEL0 SKILL_VNUM0 SKILL_LEVEL1 SKILL_VNUM1 SKILL_LEVEL2 SKILL_VNUM2 SKILL_LEVEL3 SKILL_VNUM3 SKILL_LEVEL4 SKILL_VNUM4 SP_BERSERK SP_STONESKIN SP_GODSPEED SP_DEATHBLOW SP_REVIVE" out_file_mobproto.write(mob_proto_line1 + "\r\n") mob_names_line1 = "VNUM LOCALE_NAME" out_file_mobnames.write(mob_names_line1 + "\r\n") for row in rows: mob_proto_line = "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s" % (row[0], "\"" + row[1] + "\"", get_rank(row[3]), get_type(row[4]), get_battletype(row[5]), row[6], row[7], get_flag(row[8]), row[9], get_race(row[10]), get_immune(row[11]), row[12], get_folder(row[13]), row[14], row[15], row[16], row[17], row[18], row[19], row[20], row[21], row[22], row[23], row[24], row[25], row[26], row[27], row[28], row[29], row[30], row[31], row[32], row[33], row[34], row[35], row[36], row[37], row[38], row[39], row[40], row[41], row[42], row[43], row[44], row[45], row[46], row[47], row[48], row[49], row[50], row[51], row[52], row[53], row[54], row[55], row[56], row[57], row[58], row[59], row[60], row[61], row[62], row[63], row[64], row[65], row[66], row[67], row[68], row[69], row[70], row[71]) mob_names_line = "%s\t%s" % (row[0], row[2]) out_file_mobproto.write(mob_proto_line + "\r\n") out_file_mobnames.write(mob_names_line + "\r\n") out_file_mobproto.close() return "Mob proto converted!" def item_proto(): item_type = { 0: "ITEM_NONE", 1: "ITEM_WEAPON", 2: "ITEM_ARMOR", 3: "ITEM_USE", 4: "ITEM_AUTOUSE", 5: "ITEM_MATERIAL", 6: "ITEM_SPECIAL", 7: "ITEM_TOOL", 8: "ITEM_LOTTERY", 9: "ITEM_ELK", 10: "ITEM_METIN", 11: "ITEM_CONTAINER", 12: "ITEM_FISH", 13: "ITEM_ROD", 14: "ITEM_RESOURCE", 15: "ITEM_CAMPFIRE", 16: "ITEM_UNIQUE", 17: "ITEM_SKILLBOOK", 18: "ITEM_QUEST", 19: "ITEM_POLYMORPH", 20: "ITEM_TREASURE_BOX", 21: "ITEM_TREASURE_KEY", 22: "ITEM_SKILLFORGET", 23: "ITEM_GIFTBOX", 24: "ITEM_PICK", 25: "ITEM_HAIR", 26: "ITEM_TOTEM", 27: "ITEM_BLEND", 28: "ITEM_COSTUME", 29: "ITEM_DS", 30: "ITEM_SPECIAL_DS", 31: "ITEM_EXTRACT", 32: "ITEM_SECONDARY_COIN", 33: "ITEM_RING", 34: "ITEM_BELT" } item_subtype = { 1: { 0: "WEAPON_SWORD", 1: "WEAPON_DAGGER", 2: "WEAPON_BOW", 3: "WEAPON_TWO_HANDED", 4: "WEAPON_BELL", 5: "WEAPON_FAN", 6: "WEAPON_ARROW", 7: "WEAPON_MOUNT_SPEAR", 8: "WEAPON_NUM_TYPES", }, 2: { 0: "ARMOR_BODY", 1: "ARMOR_HEAD", 2: "ARMOR_SHIELD", 3: "ARMOR_WRIST", 4: "ARMOR_FOOTS", 5: "ARMOR_NECK", 6: "ARMOR_EAR", 7: "ARMOR_NUM_TYPES", }, 3 : { 0: "USE_POTION", 1: "USE_TALISMAN", 2: "USE_TUNING", 3: "USE_MOVE", 4: "USE_TREASURE_BOX", 5: "USE_MONEYBAG", 6: "USE_BAIT", 7: "USE_ABILITY_UP", 8: "USE_AFFECT", 9: "USE_CREATE_STONE", 10: "USE_SPECIAL", 11: "USE_POTION_NODELAY", 12: "USE_CLEAR", 13: "USE_INVISIBILITY", 14: "USE_DETACHMENT", 15: "USE_BUCKET", 16: "USE_POTION_CONTINUE", 17: "USE_CLEAN_SOCKET", 18: "USE_CHANGE_ATTRIBUTE", 19: "USE_ADD_ATTRIBUTE", 20: "USE_ADD_ACCESSORY_SOCKET", 21: "USE_PUT_INTO_ACCESSORY_SOCKET", 22: "USE_ADD_ATTRIBUTE2", 23: "USE_RECIPE", 24: "USE_CHANGE_ATTRIBUTE2", 25: "USE_BIND", 26: "USE_UNBIND", 27: "USE_TIME_CHARGE_PER", 28: "USE_TIME_CHARGE_FIX", 29: "USE_PUT_INTO_BELT_SOCKET", 30: "USE_PUT_INTO_RING_SOCKET", }, 4: { 0: "AUTOUSE_POTION", 1: "AUTOUSE_ABILITY_UP", 2: "AUTOUSE_BOMB", 3: "AUTOUSE_GOLD", 4: "AUTOUSE_MONEYBAG", 5: "AUTOUSE_TREASURE_BOX", }, 5: { 0: "MATERIAL_LEATHER", 1: "MATERIAL_BLOOD", 2: "MATERIAL_ROOT", 3: "MATERIAL_NEEDLE", 4: "MATERIAL_JEWEL", 5: "MATERIAL_DS_REFINE_NORMAL", 6: "MATERIAL_DS_REFINE_BLESSED", 7: "MATERIAL_DS_REFINE_HOLLY", }, 6: { 0: "SPECIAL_MAP", 1: "SPECIAL_KEY", 2: "SPECIAL_DOC", 3: "SPECIAL_SPIRIT", }, 7: { 0 : "TOOL_FISHING_ROD", }, 8: { 0: "LOTTERY_TICKET", 1: "LOTTERY_INSTANT", }, 10: { 0: "METIN_NORMAL", 1: "METIN_GOLD", }, 12: { 0: "FISH_ALIVE", 1: "FISH_DEAD", }, 14: { 0: "RESOURCE_FISHBONE", 1: "RESOURCE_WATERSTONEPIECE", 2: "RESOURCE_WATERSTONE", 3: "RESOURCE_BLOOD_PEARL", 4: "RESOURCE_BLUE_PEARL", 5: "RESOURCE_WHITE_PEARL", 6: "RESOURCE_BUCKET", 7: "RESOURCE_CRYSTAL", 8: "RESOURCE_GEM", 9: "RESOURCE_STONE", 10: "RESOURCE_METIN", 11: "RESOURCE_ORE", }, 16: { 0: "UNIQUE_NONE", 1: "UNIQUE_BOOK", 2: "UNIQUE_SPECIAL_RIDE", 3: "UNIQUE_3", 4: "UNIQUE_4", 5: "UNIQUE_5", 6: "UNIQUE_6", 7: "UNIQUE_7", 8: "UNIQUE_8", 9: "UNIQUE_9", 10: "USE_SPECIAL", }, 28: { 0: "COSTUME_BODY", 1: "COSTUME_HAIR", }, 29: { 0: "DS_SLOT1", 1: "DS_SLOT2", 2: "DS_SLOT3", 3: "DS_SLOT4", 4: "DS_SLOT5", 5: "DS_SLOT6", }, 31: { 0: "EXTRACT_DRAGON_SOUL", 1: "EXTRACT_DRAGON_HEART", }, } wearflag = { 1: "WEAR_BODY", 2: "WEAR_HEAD", 4: "WEAR_FOOTS", 8: "WEAR_WRIST", 16: "WEAR_WEAPON", 32: "WEAR_NECK", 64: "WEAR_EAR", 128: "WEAR_SHIELD", 256: "WEAR_UNIQUE", 512: "WEAR_ARROW", 1024: "WEAR_HAIR", 2048: "WEAR_ABILITY", } limittype = { 1: "LEVEL", 2: "STR", 3: "DEX", 4: "INT", 5: "CON", 6: "PC_BANG", 7: "REAL_TIME", 8: "REAL_TIME_FIRST_USE", 9: "TIMER_BASED_ON_WEAR", } bonus = { 1: "APPLY_MAX_HP", 2: "APPLY_MAX_SP", 3: "APPLY_CON", 4: "APPLY_INT", 5: "APPLY_STR", 6: "APPLY_DEX", 7: "APPLY_ATT_SPEED", 8: "APPLY_MOV_SPEED", 9: "APPLY_CAST_SPEED", 10: "APPLY_HP_REGEN", 11: "APPLY_SP_REGEN", 12: "APPLY_POISON_PCT", 13: "APPLY_STUN_PCT", 14: "APPLY_SLOW_PCT", 15: "APPLY_CRITICAL_PCT", 16: "APPLY_PENETRATE_PCT", 17: "APPLY_ATTBONUS_HUMAN", 18: "APPLY_ATTBONUS_ANIMAL", 19: "APPLY_ATTBONUS_ORC", 20: "APPLY_ATTBONUS_MILGYO", 21: "APPLY_ATTBONUS_UNDEAD", 22: "APPLY_ATTBONUS_DEVIL", 23: "APPLY_STEAL_HP", 24: "APPLY_STEAL_SP", 25: "APPLY_MANA_BURN_PCT", 26: "APPLY_DAMAGE_SP_RECOVER", 27: "APPLY_BLOCK", 28: "APPLY_DODGE", 29: "APPLY_RESIST_SWORD", 30: "APPLY_RESIST_TWOHAND", 31: "APPLY_RESIST_DAGGER", 32: "APPLY_RESIST_BELL", 33: "APPLY_RESIST_FAN", 34: "APPLY_RESIST_BOW", 35: "APPLY_RESIST_FIRE", 36: "APPLY_RESIST_ELEC", 37: "APPLY_RESIST_MAGIC", 38: "APPLY_RESIST_WIND", 39: "APPLY_REFLECT_MELEE", 40: "APPLY_REFLECT_CURSE", 41: "APPLY_POISON_REDUCE", 42: "APPLY_KILL_SP_RECOVER", 43: "APPLY_EXP_DOUBLE_BONUS", 44: "APPLY_GOLD_DOUBLE_BONUS", 45: "APPLY_ITEM_DROP_BONUS", 46: "APPLY_POTION_BONUS", 47: "APPLY_KILL_HP_RECOVER", 48: "APPLY_IMMUNE_STUN", 49: "APPLY_IMMUNE_SLOW", 50: "APPLY_IMMUNE_FALL", 51: "APPLY_SKILL", 52: "APPLY_BOW_DISTANCE", 53: "APPLY_ATT_GRADE_BONUS", 54: "APPLY_DEF_GRADE_BONUS", 55: "APPLY_MAGIC_ATT_GRADE", 56: "APPLY_MAGIC_DEF_GRADE", 57: "APPLY_CURSE_PCT", 58: "APPLY_MAX_STAMINA", 59: "APPLY_ATTBONUS_WARRIOR", 60: "APPLY_ATTBONUS_ASSASSIN", 61: "APPLY_ATTBONUS_SURA", 62: "APPLY_ATTBONUS_SHAMAN", 63: "APPLY_ATTBONUS_MONSTER", 64: "APPLY_MALL_ATTBONUS", 65: "APPLY_MALL_DEFBONUS", 66: "APPLY_MALL_EXPBONUS", 67: "APPLY_MALL_ITEMBONUS", 68: "APPLY_MALL_GOLDBONUS", 69: "APPLY_MAX_HP_PCT", 70: "APPLY_MAX_SP_PCT", 71: "APPLY_SKILL_DAMAGE_BONUS", 72: "APPLY_NORMAL_HIT_DAMAGE_BONUS", 73: "APPLY_SKILL_DEFEND_BONUS", 74: "APPLY_NORMAL_HIT_DEFEND_BONUS", 75: "APPLY_PC_BANG_EXP_BONUS", 76: "APPLY_PC_BANG_DROP_BONUS", 77: "APPLY_EXTRACT_HP_PCT", 78: "APPLY_RESIST_WARRIOR", 79: "APPLY_RESIST_ASSASSIN", 80: "APPLY_RESIST_SURA", 81: "APPLY_RESIST_SHAMAN", 82: "APPLY_ENERGY", 83: "APPLY_DEF_GRADE", 84: "APPLY_COSTUME_ATTR_BONUS", 85: "APPLY_MAGIC_ATTBONUS_PER", 86: "APPLY_MELEE_MAGIC_ATTBONUS_PER", 87: "APPLY_RESIST_ICE", 88: "APPLY_RESIST_EARTH", 89: "APPLY_RESIST_DARK", 90: "APPLY_ANTI_CRITICAL_PCT", 91: "APPLY_ANTI_PENETRATE_PCT", } addon_type = { 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1177, 1178, 1179, 2150, 2151, 2152, 2153, 2154, 2155, 2156, 2157, 2158, 2159, 2170, 2171, 2172, 2173, 2174, 2175, 2176, 2177, 2178, 2179, 3160, 3161, 3162, 3163, 3164, 3165, 3166, 3167, 3168, 3169, 3210, 3211, 3212, 3213, 3214, 3215, 3216, 3217, 3218, 3219, 5110, 5111, 5112, 5113, 5114, 5115, 5116, 5117, 5118, 5119, 5120, 5121, 5122, 5123, 5124, 5125, 5126, 5127, 5128, 5129, 7160, 7161, 7162, 7163, 7164, 7165, 7166, 7167, 7168, 7169, 65159, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 1300, 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 2340, 2341, 2342, 2343, 2344, 2345, 2346, 2347, 2348, 2349, 3330, 3331, 3332, 3333, 3334, 3335, 3336, 3337, 3338, 3339, 5290, 5291, 5292, 5293, 5294, 5295, 5296, 5297, 5298, 5299, } errors = "" def get_item_type(type, vnum): errors = "" global errors if type in item_type: return item_type[type] else: errors += "Strange type in item %s\r\n" % vnum return item_type[0] def get_item_subtype(type, subtype, vnum): errors = "" global errors if type in item_subtype: if subtype in item_subtype[type]: return item_subtype[type][subtype] else: errors += "Strange subtype in item %s\r\n" % vnum return "NONE" def get_antiflag(antiflag, vnum): global errors str = "" if antiflag >= 131072: antiflag -= 131072 if len(str) <= 0: str = "ANTI_SAFEBOX" else: str = "ANTI_SAFEBOX | " + str if antiflag >= 65536: antiflag -= 65536 if len(str) <= 0: str = "ANTI_MYSHOP" else: str = "ANTI_MYSHOP | " + str if antiflag >= 32768: antiflag -= 32768 if len(str) <= 0: str = "ANTI_STACK" else: str = "ANTI_STACK | " + str if antiflag >= 16384: antiflag -= 16384 if len(str) <= 0: str = "ANTI_PKDROP" else: str = "ANTI_PKDROP | " + str if antiflag >= 8192: antiflag -= 8192 if len(str) <= 0: str = "ANTI_GIVE" else: str = "ANTI_GIVE | " + str if antiflag >= 4096: antiflag -= 4096 if len(str) <= 0: str = "ANTI_SAVE" else: str = "ANTI_SAVE | " + str if antiflag >= 2048: antiflag -= 2048 if len(str) <= 0: str = "ANTI_EMPIRE_C" else: str = "ANTI_EMPIRE_C | " + str if antiflag >= 1024: antiflag -= 1024 if len(str) <= 0: str = "ANTI_EMPIRE_B" else: str = "ANTI_EMPIRE_B | " + str if antiflag >= 512: antiflag -= 512 if len(str) <= 0: str = "ANTI_EMPIRE_A" else: str = "ANTI_EMPIRE_A | " + str if antiflag >= 256: antiflag -= 256 if len(str) <= 0: str = "ANTI_SELL" else: str = "ANTI_SELL | " + str if antiflag >= 64: antiflag -= 64 if len(str) <= 0: str = "ANTI_GET" else: str = "ANTI_GET | " + str if antiflag >= 32: antiflag -= 32 if len(str) <= 0: str = "ANTI_MUDANG" else: str = "ANTI_MUDANG | " + str if antiflag >= 16: antiflag -= 16 if len(str) <= 0: str = "ANTI_SURA" else: str = "ANTI_SURA | " + str if antiflag >= 8: antiflag -= 8 if len(str) <= 0: str = "ANTI_ASSASSIN" else: str = "ANTI_ASSASSIN | " + str if antiflag >= 4: antiflag -= 4 if len(str) <= 0: str = "ANTI_MUSA" else: str = "ANTI_MUSA | " + str if antiflag >= 2: antiflag -= 2 if len(str) <= 0: str = "ANTI_MALE" else: str = "ANTI_MALE | " + str if antiflag >= 1: antiflag -= 1 if len(str) <= 0: str = "ANTI_FEMALE" else: str = "ANTI_FEMALE | " + str if antiflag == 0 and len(str) > 0: return "\"" + str + "\"" else: errors += "Strange antiflag in item %s\r\n" % vnum return "\"NONE\"" def get_flag(flag, vnum): global errors str = "" if flag >= 32768: flag -= 32768 if len(str) <= 0: str = "ITEM_APPLICABLE" else: str = "ITEM_APPLICABLE | " + str if flag >= 16384: flag -= 16384 if len(str) <= 0: str = "REFINEABLE" else: str = "REFINEABLE | " + str if flag >= 8192: flag -= 8192 if len(str) <= 0: str = "LOG" else: str = "LOG | " + str if flag >= 4096: flag -= 4096 if len(str) <= 0: str = "ITEM_QUEST" else: str = "ITEM_QUEST | " + str if flag >= 2048: flag -= 2048 if len(str) <= 0: str = "QUEST_GIVE" else: str = "QUEST_GIVE | " + str if flag >= 1024: flag -= 1024 if len(str) <= 0: str = "QUEST_USE_MULTIPLE" else: str = "QUEST_USE_MULTIPLE | " + str if flag >= 512: flag -= 512 if len(str) <= 0: str = "QUEST_USE" else: str = "QUEST_USE | " + str if flag >= 256: flag -= 256 if len(str) <= 0: str = "CONFIRM_WHEN_USE" else: str = "CONFIRM_WHEN_USE | " + str if flag >= 128: flag -= 128 if len(str) <= 0: str = "ITEM_IRREMOVABLE" else: str = "ITEM_IRREMOVABLE | " + str if flag >= 64: flag -= 64 if len(str) <= 0: str = "ITEM_MAKECOUNT" else: str = "ITEM_MAKECOUNT | " + str if flag >= 32: flag -= 32 if len(str) <= 0: str = "ITEM_UNIQUE" else: str = "ITEM_UNIQUE | " + str if flag >= 16: flag -= 16 if len(str) <= 0: str = "ITEM_SLOW_QUERY" else: str = "ITEM_SLOW_QUERY | " + str if flag >= 8: flag -= 8 if len(str) <= 0: str = "COUNT_PER_1GOLD" else: str = "COUNT_PER_1GOLD | " + str if flag >= 4: flag -= 4 if len(str) <= 0: str = "ITEM_STACKABLE" else: str = "ITEM_STACKABLE | " + str if flag >= 2: flag -= 2 if len(str) <= 0: str = "ITEM_SAVE" else: str = "ITEM_SAVE | " + str if flag >= 1: flag -= 1 if len(str) <= 0: str = "ITEM_TUNABLE" else: str = "ITEM_TUNABLE | " + str if flag == 0 and len(str) > 0: return "\"" + str + "\"" else: errors += "Strange flag in item %s\r\n" % vnum return "\"NONE\"" def get_wearflag(wear, vnum): global errors if wear in wearflag: return "\"" + wearflag[wear] + "\"" else: errors += "Strange wearflag in item %s\r\n" % vnum return "\"NONE\"" def get_immuneflag(immune): return "" def get_limittype(limit): if limit in limittype: return "\"" + limittype[limit] + "\"" else: return "\"LIMIT_NONE\"" def get_apply(apply): if apply in bonus: return "\"" + bonus[apply] + "\"" else: return "\"APPLY_NONE\"" def socket(sockett): if sockett == 127: return 0 else: return sockett print "Connecting to database proto..." data = "player" db = MySQLdb.connect(host_mysql,user_mysql,passwd_mysql,data) cur = db.cursor() print "Connected." cur.execute("select * from item_proto") rows = cur.fetchall() out_file_itemproto = open("item_proto.txt", "w") out_file_itemnames = open("item_names.txt", "w") print "Converting item_proto..." item_proto_line1 = "VNUM NAME TYPE SUBTYPE SIZE ANTIFLAG FLAG WEARFLAG IMMUNEFLAG GOLD SHOP_BUY_PRICE REFINED_VNUM REFINE_SET MAGIC_PCT LIMITTYPE0 LIMITVALUE0 LIMITTYPE1 LIMITVALUE1 APPLYTYPE0 APPLYVALUE0 APPLYTYPE1 APPLYVALUE1 APPLYTYPE2 APPLYVALUE2 VALUE0 VALUE1 VALUE2 VALUE3 VALUE4 VALUE5 SPECULAR SOCKET_PCT ADDON_TYPE" out_file_itemproto.write(item_proto_line1 + "\r\n") item_names_line1 = "VNUM LOCALE_NAME" out_file_itemnames.write(item_names_line1 + "\r\n") for row in rows: item_proto_line = "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s" % (row[0], "\"" + row[2] + "\"", "\"" + get_item_type(row[4], row[0]) + "\"" , "\"" + get_item_subtype(row[4], row[5], row[0]) + "\"", row[7] , get_antiflag(row[8], row[0]), get_flag(row[9], row[0]), get_wearflag(row[10], row[0]), get_immuneflag(row[11]), row[12], row[13], row[14], row[15], row[17], get_limittype(row[18]), row[19], get_limittype(row[20]), row[21], get_apply(row[22]), row[23], get_apply(row[24]), row[25], get_apply(row[26]), row[27], row[28], row[29], row[30], row[31], row[32], row[33], row[40], row[41], row[42]) item_names_line = "%s\t%s" % (row[0], row[3]) out_file_itemproto.write(item_proto_line + "\r\n") out_file_itemnames.write(item_names_line + "\r\n") out_file_itemproto.close() print "Item proto converted!" """if len(errors) != 0: print "Errors during conversion:" print errors""" print item_proto() print mob_proto() Note: Please watch your rows! It needs to match with your item_proto tables row order structure: item_proto_line = "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s" % (row[0], "\"" + row[1] + "\"", "\"" + get_item_type(row[3], row[0]) + "\"" , "\"" + get_item_subtype(row[3], row[4], row[0]) + "\"", row[6] , get_antiflag(row[7], row[0]), get_flag(row[8], row[0]), get_wearflag(row[9], row[0]), get_immuneflag(row[10]), row[11], row[12], row[13], row[14], row[16], get_limittype(row[17]), row[18], get_limittype(row[19]), row[20], get_apply(row[21]), row[22], get_apply(row[23]), row[24], get_apply(row[25]), row[26], row[27], row[28], row[29], row[30], row[31], row[32], row[39], row[40], row[41]) Mine is: item_proto_line = "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s" % (row[0], "\"" + row[2] + "\"", "\"" + get_item_type(row[4], row[0]) + "\"" , "\"" + get_item_subtype(row[4], row[5], row[0]) + "\"", row[7] , get_antiflag(row[8], row[0]), get_flag(row[9], row[0]), get_wearflag(row[10], row[0]), get_immuneflag(row[11]), row[12], row[13], row[14], row[15], row[17], get_limittype(row[18]), row[19], get_limittype(row[20]), row[21], get_apply(row[22]), row[23], get_apply(row[24]), row[25], get_apply(row[26]), row[27], row[28], row[29], row[30], row[31], row[32], row[33], row[40], row[41], row[42]) Also check: item_names_line = "%s\t%s" % (row[0], row[2]) Mine is: item_names_line = "%s\t%s" % (row[0], row[3])
-
Wooow @HAMLET, you are a lifesaver! I had this stupid bug from the begining, I think fog was the problem when you stepped on the bridge, before the fix: After the fix working flawlessly: I don't have problems like @muiekanzidor mentioned, entity shadows casted well on the ground after the fix. (Note: I don't implemented the dynamic shadows system, just extended the mobs/other dynamic entities shadow range.)
-
Personally I partially don't recommend to implement this to your server because the bridge problem. The other downside is at the distant terrain where there are no mobs/npcs just buildings/trees and the terrain there will be no shadows because the real time rendering is limited to a specific distance. The other issue is objects which placed partially undergrond like a bridge a tree, the tree models have a circle base and it will be casted to the grass which is above them or a bridge pillar's shadow could be seen casted on the ground texture. The idea is good but the classic static shadowmapping has much advantages like shadows are rendered allways at the distant terrain. Not to mention the dinamic shadows are shaking when you ride a horse or run, they are not stable. Implement that fixes which @ CONTROL mentioned so mob/other dynamic shadows will be casted further, keep the old static lightmapping engine until the issues I mentioned are not fixed.
-
If you are a masochist like me, and you stucked using the sh*tty Terenzo client source as me, you need to modify the GameLib/MapOutdoorRenderSTP.cpp file as well! Search: if (isFogEnable) { STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, TRUE); STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, 0xFFFFFFFF); STATEMANAGER.SetTexture(0, pTerrain->GetShadowTexture()); STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, rkTPRS.m_dwFogColor); STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE); } else { STATEMANAGER.SetTexture(0, pTerrain->GetShadowTexture()); STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); } Modify like this (add the STATEMANAGER.SetTexture(0, nullptr); lines to the correct place): if (isFogEnable) { STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, TRUE); STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, 0xFFFFFFFF); STATEMANAGER.SetTexture(0, nullptr); STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); STATEMANAGER.SetRenderState(D3DRS_FOGCOLOR, rkTPRS.m_dwFogColor); STATEMANAGER.SetRenderState(D3DRS_FOGENABLE, FALSE); } else { STATEMANAGER.SetTexture(0, nullptr); STATEMANAGER.DrawIndexedPrimitive(ePrimitiveType, 0, m_iPatchTerrainVertexCount, 0, wPrimitiveCount); } Search: void CMapOutdoor::__SoftwareTransformPatch_ApplyStaticShadowRenderState() { STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR); STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG2, D3DTA_DIFFUSE); STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE); STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); STATEMANAGER.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); STATEMANAGER.SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); STATEMANAGER.SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); } Modify like this: void CMapOutdoor::__SoftwareTransformPatch_ApplyStaticShadowRenderState() { STATEMANAGER.SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); STATEMANAGER.SetRenderState(D3DRS_DESTBLEND, D3DBLEND_SRCCOLOR); STATEMANAGER.SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_CURRENT); STATEMANAGER.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); } And now you are good to go!
-
I really want to implement this to my server but I cant, I always get some errors while I try to compile the server side codes. The first is config.cpp, I see my compiler doesn't like the unique_ptr, if I write auto_ptr instead, it gives me less error: 'pMsg' was not declared in this scope I had to modify the input_p2p.cpp file from this: for (auto it = set.begin(); it != set.end(); ++it) To this: for (DESC_MANAGER::DESC_SET::const_iterator it = set.begin(); it != set.end(); ++it) To not get compiling error. But I can't figure out how to solve the pMsg related error. My client compiler (VS2013 shitty Terenzo files) also had a hard time when I put this line: #ifdef __NEW_CLIENT_VERSION_CHECK__ strncpy(LoginPacket.clientVersion, g_ClientVersion.c_str(), sizeof(LoginPacket.clientVersion)); #endif To: if (!openid_test) { [...] }else{ [...] // 비밀번호를 메모리에 계속 갖고 있는 문제가 있어서, 사용 즉시 날리는 것으로 변경 #ifdef __NEW_CLIENT_VERSION_CHECK__ strncpy(LoginPacket.clientVersion, g_ClientVersion.c_str(), sizeof(LoginPacket.clientVersion)); #endif [...] } As you suggested, I could only compile it if I put it outside of the if (!openid_test)'s else case under the second corean text, If I put it to the suggested place I got "takes 3 argoument" errors (sorry I didn't remember the exact message). I tried to compile under an C++17 upgraded FreeBSD9.2 VDI but I could't compile it there too. Could you recommend a good VDI to compile your code? Or the tutorial has some wrong steps? Also the Locale_inc.h, packet.h, PythonNetworkStreamPhaseGame.cpp files are 0KB empty files in the UserInterface tutorial folder, can I be sure there are nothing to modify there? Tomorrow I try it again with a FreeBSD12 VDI with a CLANG-9 compiler, if I don't succeed there I will sadly revert these changes and I go back to my old python method where players clients send their messages in the global chat like this via uichat.py and uiwhisper.py: PlayerName [v0.1]: Message I hope I could implement your release to my server someday! Thanks if you could help me or us somehow!
-
Problem with Browser
Werwolf94 replied to Lux Arcadia's topic in Community Support - Questions & Answers
I have the same problem, @ TMP4 is correct, the ENB Series graphical mod cause this. I also use that engine, what we need is to send a client a SHIFT+F12 keypress command via py script (without a real keypress) to turn off the graphical engine when you open the ItemShop and a Shift+F12 again when you close the shop to turn the engine back on. If anyone could help make this to work please help us, yes, it's an annoying bug. -
So if I use the classic MYSQL protos I need to swap wearflags: 128: "WEAR_SHIELD", 256: "WEAR_UNIQUE", And also in my convert_test.py which is convert the db protos to client side txt ones. (If anyone needs it please let me know!) Thanks for the fix, I will implement to my server tomorrow!
- 1 reply
-
- 1
-
-
The project is halted a bit because my personal life and because partially my job. My brother moved to the capital city from countryside so I helped him out with the moving. My workplace is a bit messy because the extreme summer heat, I work at the hungarian railway company as a manual railroad crossing gate and railroad switch operator and I have a lot of problems with the railroad crossings which are remotely operated (their "brain" gets stupid from the heat and I need to take action remotely to prevent accidents). Normally if there is no error I can work with the server in my workplace because in one hour maybe one or two trains pass at the station where I work. I currently applied small fixes like guild mark upload problem resolving, and I work on a special quest where the black wind clan take you as prissoner to a special 1x2 quest exclusive map where you need to break free to get out from there, I'ts a revenge from the black wind clan to the player because you helped a villagers a lot in the prevoius quests. Yes, I want to write more quests currently I have nearly 30 working quests which were made by me. I planned to open the server at last christmas, and I delayed it to this summer but I think it will be autumn or christmas.
-
Thanks for the replies, finally I made a shell script for the public IP address change. I want to share it with you (please if someone expert see this revise my code), so I put this at the end of my etc/crontab file (this will run the usr/game/ipcheck.sh shell script every 10 minutes): # #Check for IP change # */10 * * * * root (cd /usr/game/ && sh ipcheck.sh) The ipcheck.sh file: #! /bin/sh detectedIpAddress=`curl -s checkip.dyndns.org | sed -e 's/.*Current IP Address: //' -e 's/<.*$//'` if [ -z "$detectedIpAddress" ]; then exit 0 fi if test -f /tmp/ipaddress then previousIpAddress=`cat /tmp/ipaddress` else previousIpAddress="0.0.0.0" fi if [ "$detectedIpAddress" != "$previousIpAddress" ] then if pgrep 'db' > /dev/null then while pgrep "game"; do killall -6 game sleep 3 echo `date +"%Y-%m-%d %T"` ": IP address changed, gamecore shutting down." >> /tmp/state done if ps ax | grep -v grep | grep 'game' > /dev/null then echo `date +"%Y-%m-%d %T"` " Game not running." >> /tmp/state else cd /usr/game/auth ./auth & sleep 2 echo `date +"%Y-%m-%d %T"` ": AUTH restarted." >> /tmp/state cd /usr/game/channel1 ./game & sleep 2 echo `date +"%Y-%m-%d %T"` ": CH1 restarted." >> /tmp/state cd /usr/game/game99 ./game & sleep 2 echo `date +"%Y-%m-%d %T"` ": CH99 restarted." >> /tmp/state fi else echo `date +"%Y-%m-%d %T"` ": DB not running." >> /tmp/state fi echo $detectedIpAddress > /tmp/ipaddress fi If you want to use it, I give you some note, please remove the -6 argument from the killall -6 game if you want safer operation (my gamefile with the default -1 killall don't want to properly shutdown, it's starting and endless killprocess which never ends so that's why I use the -6 (abort) argument). So, this shell script will create an ipaddress file to your tmp folder and also a state file for logging. If you want to test out the script delete the ipaddress file and it behaves like the public IP changed. The script only takes action when your server is running ("if pgrep 'db' > /dev/null" checks your DB core is running, if not it throws a "DB not running message" every 10 minutes, it's 34byte so it takes time to grow huge). The script also won't shutdown the DB core because when the IP changes the only problem we facing is the game throws back us to the serverselecting menu screen so the DB shutdown I think don't necessary. I use PROXY_IP: servername.tplinkdns.com at the core config files, I don't have BIND_IP entry! Some sidenotes which I worry about: -This script and the IP change can cause items/progression loss for the players (7-10 minute maximum), because we can't execute ingame /shutdown command from outside (and the -6 argument which I mentioned before) -The server downtime maybe is 10-20 minutes while this script brings back the server online, but it's automatic so that's not a problem if you're not at home -I don't know what happen if the script runs exactly when the IP changing happen, I think the script behaves well when the IP change occurs minutes before the script runs down I bought a 600VA Legrand UPS to protect the server PC and our fiber optic Internet moden from the micro power outages, but I can't bring NUT to work. If someone is experienced with NUT, you are welcome to tell what I need to config to get start working (NUT is a FreeBSD service which communicates with the UPS via the USB-A (PC side) USB-B (UPS side) cable, if the UPS sends a message like Power level is 25%, FreeBSD can execute a graceful shutdown to prevent data loss which is only fixable with FSCK command.) I tested the 600VA UPS, it can run the internet modem and the server for 15 minutes, but I really need the working NUT configuration to achieve communication with the UPS. I can agree with you FrenchForeignLegion the traceroute maybe better when you own a VPS (my hop number from outside is above 8). And for the end a funny note: the owner of the JZT Kft. made a phone call with me. He spoke about it cannot be the case which I mentioned for them about their shitty network, he told me maybe I misconfigured my FreeBSD and that's the case why the lags and kicks happen. He offered a free trial month of a Ryzen VPS (and he also told me the XXL VPS is not enough for a Metin2 server which I was rent from them for years). He also mentioned my server will not be optimal for handling 100-150 players with my home connection.
-
Hi! It's been a long time since I paid a VPS Server from a hungarian company called JZT Kft. I don't opened the server for public, it was just in test and development phase. The original idea was to open the server with this VPS, but when we tested with 2-3 people kicks and lags occured. In the last year the FTP connection went so slow, sometimes 3MB/s was the total downstream speed from the server (the average was 30-60MB/s). I restricted the autopatcher folder in my webserver to 50Kb/s so if I released a patch if the file size is up to 20-90MB the download time was 10-20-30 minutes! (I made this decision because I know the VPS's poor network connection.) The only upside was the VPS had Static IP address so the domain was easy to manage: A record was the static IP of the VPS CNAME record was the www.servername.com which pointed to the A record. So, long story short I decided I will end the VPS subscription in next month and move to my I think pretty good desktop PC: CPU: AMD FX6350 (6 core 3.9GHz CPU with 125W maximal power consumption) RAM: 16GB SAMSUNG 1600MHz DDR3 memory modules in dual channel (4 pieces each RAM is 4GB) MOBO: ASUS M5A97 PSU: It's a simple 400W one with replaced brand new air went. GPU: A 64MB or 128MB (sorry don't know exactly) PCIE one with no air vent Network connection: 9-14 miliseconds of ping, nearly 900-950MB/s Down/Upstream (I have a pretty good optical connection so the patcher can take 300MB/s from it.) But... I have dynamic IP address to make this good facts worse. I try to workaround this so I set up a tplinkdns address (similar to No-IP) which is updated by my router if the ISP decides to give me another IP than before. Let's start with the Domain address, I deleted the A record and only use a CNAME record which is redirected to the tplinkdns address which tracks down my IP if it changes. The only downside is my website is unreachable if you type it similar like this: [Hidden Content] it's only reachable when you type it like this: [Hidden Content] so the www. is needed I think because the missing A record which we can't set because the IP is changing weekly or in 2-3 days. So why don't you buy a static IP from your ISP guess you ask me, sadly the ISP don't offer static IP address to home users even if you want to pay for it (it's Magyar Telekom (T-Com) btw.), so only businesses can only have static IP from this ISP (sadly in Hungary the government closed that opportunity where you can start a self employed mini business with only 50K HUF ~125EUR tax per month it was named "KATA self employment" if I translate it correctly, now the smallest option is start a Bt. (general partnership company) or a Kft. (limited partnership company) where you need millions of Forint's to just start the company. The KATA self employment option is sadly only avaliable for those who's only job is the self employment company so you can't make a KATA if you have a main job like me (I work at te hungarian railway company (don't laugh at me please) as a manual road crossing gate operator and I operate track switch by levers). So I manged to configure the Apache and the PHP server, pointing to the machine's local IP address, and it works well. The server core's set to PROXY IP: servername.tplinkdns.com (I don't use the BIND IP variable). I have a fear if the IP changes I need to restart or reboot the server because the cores only set the PROXY IP's when the gameserver boot's up if the IP changes when the server online I guess it will kicks out the players and you can not login to it. I set the autopatcher and the client's serverinfo.py also to the tplinkdns address, my only fear is the game cores. Thanks for the suggestions, have a nice day!
-
I share my solution for people who use older sources: Lets start with the char_item.cpp! Add this include: #include "wedding.h" Search: if (true == IsRiding()) { ChatPacket(CHAT_TYPE_INFO, LC_TEXT("둔갑할 수 없는 상태입니다.")); return false; } Add under (with this code we will block the use of polymorph marble if the player is at one of the blocked maps): if ((marriage::WeddingManager::instance().IsWeddingMap(GetMapIndex()) == true) || (CWarMapManager::instance().IsWarMap(GetMapIndex()) == true) || ( CArenaManager::instance().IsArenaMap(GetMapIndex()) == true ) || (GetMapIndex() == 113)) { if (IsAffectFlag(AFFECT_POLYMORPH)) RemoveAffect(AFF_POLYMORPH); ChatPacket(CHAT_TYPE_INFO, LC_TEXT("여기서는 변경할 수 없습니다.")); return false; } Now let's head to the char_affect.cpp! Add this two includes: #include "war_map.h" #include "wedding.h" Search for: if ( CArenaManager::instance().IsArenaMap(GetMapIndex()) == true ) { RemoveGoodAffect(); } Replace with this (this will polymorph back the player at Duel Arena map if he/she enters as polymorphed): if ( CArenaManager::instance().IsArenaMap(GetMapIndex()) == true ) { RemoveGoodAffect(); if (IsPolymorphed() == true) { SetPolymorph(0); RemoveAffect(AFFECT_POLYMORPH); } } Add under (this will polymorph back the player at Guild war Arena/Guild Flag war map/Wedding/OX if he/she enters as polymorphed : if ((CWarMapManager::instance().IsWarMap(GetMapIndex()) == true) || (marriage::WeddingManager::instance().IsWeddingMap(GetMapIndex()) == true) || (GetMapIndex() == 113)) { if (IsPolymorphed() == true) { SetPolymorph(0); RemoveAffect(AFFECT_POLYMORPH); } } And finally write this to your locale_string.txt: "여기서는 변경할 수 없습니다."; "You cannot polymorph at this map!"; Video proof:
-
I will open my server in early December. My target goal is bring back the gold 2009-2011 era. But with a serious twist, with brand new maps! The only original maps will be: wedding, ox, duel, the two guild war maps. The main goal is to simulate the 2009 feeling when everything was new for you, you don't know where the mobs/bosses/metins etc, so you needed to explore the world around you. The oldschool servers biggest mistake is I think is using the old original maps, because you played n+1 times and you know every trick, every position, where to go when. There will be no: -Dragon soul/Alchemy -Belt -Pets/Mounts -Even the menu is oldschool there is no virtual keyboard -There will be no 6-7 bonuses -GF drops with pvm/quest based progression system -3 new nation where the new players arranged randomly when you register in the homepage (invite code system is avaliable to get the same nation with your friends) -There are no empire specific maps, the first map Yeongdong is the "capital city" where PVP is only allowed in the middle circle, all other maps are commonly used by every empire -There will be no paid itemshop, the Dragon Coin is only accessible through the alternative drop so it's 100% free -Passive dragon coin gaining system where you gain 1DC for 10 minutes gameplay time -And so on The development by myself was started in 2015. This video is a bit outdated, but here is some footage from my channel: Sadly it will be hungarian exclusive, I don't had time to write every new quest in english, but I think this server will shake up the hungarian Metin2 privateserver gaming community. Bonus footage, I like to write quest where you interact with the environment:
-
Hi! Maybe your problem is using the shitty Terenzo client source like me. Check your PythonBackground.cpp file and look for these two lines: m_kMap_dwTargetID_dwChrID.insert(make_pair(dwID, dwChrVID)); Change (add ::std before make_pair): m_kMap_dwTargetID_dwChrID.insert(std::make_pair(dwID, dwChrVID)); And: m_kMap_dwID_kReserveTargetEffect.insert(make_pair(dwID, ReserveTargetEffect)); Change (add ::std before make_pair): m_kMap_dwID_kReserveTargetEffect.insert(std::make_pair(dwID, ReserveTargetEffect)); Tested and bug not present anymore in my server (I completed all quest with my GM character). Please tell me your results!
-
Hi @ Mali, thanks for this cool feature! I had just one little problem in VS2013 (I use the shitty Terenzo source instead of Novaline). With: constexpr DWORD g_dwMinimapSmoothZoomMSec = 500; // Upper = Slower The compiler said: Error 1 error C2146: syntax error : missing ';' before identifier 'DWORD' C:\VS\client\UserInterface\PythonMiniMap.cpp 68 1 UserInterface Error 2 error C4430: missing type specifier - int assumed. Note: C++ does not support default-int C:\VS\client\UserInterface\PythonMiniMap.cpp 68 1 UserInterface I changed it to: const DWORD g_dwMinimapSmoothZoomMSec = 500; // Upper = Slower Works like charm In the readme file I had a problem with the first code block (with the constexpr DWORD g_dwMinimapSmoothZoomMSec = 500; // Upper = Slower block), I added too low in the cpp file first, i put it before: void CPythonMiniMap::SetScale(float fScale) { if (fScale >= 4.0f) fScale = 4.0f; if (fScale <= 0.5f) fScale = 0.5f; m_fScale = fScale; __SetPosition(); } But that was produced some errors for me, at the second try I added after the: void CPythonMiniMap::RemoveObserver(DWORD dwVID) { m_kMap_dwVID_kObserver.erase(dwVID); } Now it's compilable. Thank's again for this great release!
