Jump to content

Cappuccino

Seller
  • Posts

    47
  • Joined

  • Last visited

  • Days Won

    1
  • Feedback

    0%

Everything posted by Cappuccino

  1. Thanks, this is exactly what I was looking for. I'll download the html and images and hook it to my cms Do you have other links from that website of other old chinese servers?
  2. Does anyone have the old website which came with these files?
  3. Yes you can, but the bonus values will be shared with normal items. For example, you might want to set a different bonus value for "chance of critical damage" for costumes.
  4. Yes, of course. You can drop the not necessary columns if you want but more modificaitons to the source are required.
  5. Can you post on of your biologist quest? The problem might be with the quest itself
  6. Does anyone have the very old chinese website which many servers where using with raiin server files? The one that had a vertical banner and was totally in chinese
  7. Have you implemented the item_scale.txt in your client? Probably coordinates are wrong in the item_scale.txt file or you should change the coordinates offset in your client source to move the wing
  8. There instructions have been tested on FreeBSD 12.1! First of all we want to install update the package repository: pkg update If you have never used pkg probably you will be asked to install it. Now run this command to install php7.4 and nginx pkg install php74 nginx We can install the most common php extensions running this command: pkg install php74-extensions php74-mysqli php74-mbstring php74-curl php74-gd The following extensions will be installed: php74-ctype: 7.4.14 php74-curl: 7.4.14 php74-dom: 7.4.14 php74-extensions: 1.0 php74-filter: 7.4.14 php74-gd: 7.4.14 php74-iconv: 7.4.14 php74-json: 7.4.14 php74-mbstring: 7.4.14 php74-mysqli: 7.4.14 php74-opcache: 7.4.14 php74-pdo: 7.4.14 php74-pdo_sqlite: 7.4.14 php74-phar: 7.4.14 php74-posix: 7.4.14 php74-session: 7.4.14 php74-simplexml: 7.4.14 php74-sqlite3: 7.4.14 php74-tokenizer: 7.4.14 php74-xml: 7.4.14 php74-xmlreader: 7.4.14 php74-xmlwriter: 7.4.14 Enable nginx and php service to automatically start sysrc nginx_enable=yes sysrc php_fpm_enable=YES We can start nginx and php for the first time by running service nginx start service php-fpm start You can open now your web browser and type the server ip in the address bar. You should see a page like this We are going to configure nginx now. Open the file nginx.conf located in /usr/local/etc/nginx and modify the section "server": server { listen 80; server_name _; root /var/www; index index.php index.html index.htm; location / { try_files $uri $uri/ =404; } location ~ \.php$ { try_files $uri =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $request_filename; include fastcgi_params; } location ~ /\.ht { deny all; } } Change mydomainname.com with your domain (or server ip). We can test now if php is working correctly. The files of your webiste will be hosted in the folder /var/www (you can change it in the configuration above). Create a new file inside that folder and call it index.php with this content: <?php phpinfo(); Now open again the browser and type the ip address/domain name and you should see something like this: The server is working properly and you can upload now your script You might need to install more php extentions according to the requirements of your script
  9. I'm posting this since some people have requested this tutorial. It's very easy. In the locale folder of your server look for questlib.lua and search special.active_skill_list = { { { 1, 2, 3, 4, 5}, { 16, 17, 18, 19, 20}, }, { {31, 32, 33, 34, 35}, {46, 47, 48, 49, 50}, }, { {61, 62, 63, 64, 65, 66}, {76, 77, 78, 79, 80, 81}, }, { {91, 92, 93, 94, 95, 96}, {106, 107, 108, 109, 110, 111}, }, } edit it like this special.active_skill_list = { { { 1, 2, 3, 4, 5}, { 16, 17, 18, 19, 20}, }, { {31, 32, 33, 34, 35}, {46, 47, 48, 49, 50}, }, { {61, 62, 63, 64, 65, 66}, {76, 77, 78, 79, 80, 81}, }, { {91, 92, 93, 94, 95, 96}, {106, 107, 108, 109, 110, 111}, }, { {170,171,172,173,174,175}, }, } done
  10. This is a little tutorial on how to connect the game to the item shop of your website. By clicking on the coin in the game client the web browser will be opened and connected to your website. I'll explain how to automatically login the player to the item shop First of all open cmd_general.cpp and look for do_in_game_mall and replace the whole function with this ACMD(do_in_game_mall) { char buf[512+1]; char sas[33]; MD5_CTX ctx; const char secretKey[] = "my secret key"; // <<--- EDIT THIS!!! const char websiteUrl[] = "[Hidden Content]"; // <<--- EDIT THIS!!! snprintf(buf, sizeof(buf), "%u%s", ch->GetAID(), secretKey); MD5Init(&ctx); MD5Update(&ctx, (const unsigned char *) buf, strlen(buf)); #ifdef __FreeBSD__ MD5End(&ctx, sas); #else static const char hex[] = "0123456789abcdef"; unsigned char digest[16]; MD5Final(digest, &ctx); int i; for (i = 0; i < 16; ++i) { sas[i+i] = hex[digest[i] >> 4]; sas[i+i+1] = hex[digest[i] & 0x0f]; } sas[i+i] = '\0'; #endif snprintf(buf, sizeof(buf), "mall %s?aid=%u&secret=%s", websiteUrl, ch->GetAID(), sas); ch->ChatPacket(CHAT_TYPE_COMMAND, buf); } Edit secretKey and websiteUrl with your information. The key can be a random string. What happens is the following: aid = account id secret = md5( account id + your secret key ) So your website you can check if the secret is corrent and then login the player. You can do something like this: <?php $secretKey = $_GET['secret']; $accountId = $_GET['aid']; $generatedSecret = md5($accountId . $secretKey); if ($generatedSecret == $secretKey) { // ok, proceed with login } else { // invalid secret }
  11. Costume bonuses are taken from item_attr table but this is quite a limit. We are going to create a second table item_attr_costume which will contain only costume bonuses. Transform costume and Enchant costume will take bonus from the new table item_attr_costume. Let's start. Open ClientManagerBoot.cpp and add at the end bool CClientManager::InitializeCostumeAttrTable() { char query[4096]; snprintf(query, sizeof(query), "SELECT apply, apply+0, prob, lv1, lv2, lv3, lv4, lv5, weapon, body, wrist, foots, neck, head, shield, ear FROM item_attr_costume%s ORDER BY apply", GetTablePostfix()); std::unique_ptr<SQLMsg> pkMsg(CDBManager::instance().DirectQuery(query)); SQLResult* pRes = pkMsg->Get(); if (!pRes->uiNumRows) { sys_err("no result from item_attr_costume"); return false; } if (!m_vec_costumeAttrTable.empty()) { sys_log(0, "RELOAD: item_attr_costume"); m_vec_costumeAttrTable.clear(); } m_vec_costumeAttrTable.reserve(pRes->uiNumRows); MYSQL_ROW data; while ((data = mysql_fetch_row(pRes->pSQLResult))) { TItemAttrTable t{}; int col = 0; strlcpy(t.szApply, data[col++], sizeof(t.szApply)); str_to_number(t.dwApplyIndex, data[col++]); str_to_number(t.dwProb, data[col++]); str_to_number(t.lValues[0], data[col++]); str_to_number(t.lValues[1], data[col++]); str_to_number(t.lValues[2], data[col++]); str_to_number(t.lValues[3], data[col++]); str_to_number(t.lValues[4], data[col++]); str_to_number(t.bMaxLevelBySet[ATTRIBUTE_SET_WEAPON], data[col++]); str_to_number(t.bMaxLevelBySet[ATTRIBUTE_SET_BODY], data[col++]); str_to_number(t.bMaxLevelBySet[ATTRIBUTE_SET_WRIST], data[col++]); str_to_number(t.bMaxLevelBySet[ATTRIBUTE_SET_FOOTS], data[col++]); str_to_number(t.bMaxLevelBySet[ATTRIBUTE_SET_NECK], data[col++]); str_to_number(t.bMaxLevelBySet[ATTRIBUTE_SET_HEAD], data[col++]); str_to_number(t.bMaxLevelBySet[ATTRIBUTE_SET_SHIELD], data[col++]); str_to_number(t.bMaxLevelBySet[ATTRIBUTE_SET_EAR], data[col++]); m_vec_costumeAttrTable.push_back(t); } return true; } Search if (!InitializeItemRareTable()) { sys_err("InitializeItemRareTable FAILED"); return false; } add under if (!InitializeCostumeAttrTable()) { sys_err("InitializeCostumeAttrTable FAILED"); return false; } open ClientManager.h and look for bool InitializeMonarch(); add under bool InitializeCostumeAttrTable(); look for std::vector<TItemAttrTable> m_vec_itemRareTable; add under std::vector<TItemAttrTable> m_vec_costumeAttrTable; open ClientManager.cpp and look for tmp->EncodeWORD(m_vec_itemRareTable.size()); tmp->Encode(&m_vec_itemRareTable[0], sizeof(TItemAttrTable) * m_vec_itemRareTable.size()); add under tmp->EncodeWORD(m_vec_costumeAttrTable.size()); tmp->Encode(&m_vec_costumeAttrTable[0], sizeof(TItemAttrTable) * m_vec_costumeAttrTable.size()); look for sizeof(WORD) + sizeof(WORD) + sizeof(TItemAttrTable) * m_vec_itemRareTable.size() + add under sizeof(WORD) + sizeof(WORD) + sizeof(TItemAttrTable) * m_vec_costumeAttrTable.size() + look for tmp->EncodeHeader(HEADER_DG_RELOAD_PROTO, 0, sizeof(WORD) + sizeof(TSkillTable) * m_vec_skillTable.size() + sizeof(WORD) + sizeof(TBanwordTable) * m_vec_banwordTable.size() + sizeof(WORD) + sizeof(TItemTable) * m_vec_itemTable.size() + sizeof(WORD) + sizeof(TMobTable) * m_vec_mobTable.size() + sizeof(WORD) + sizeof(TShopTable) * m_iShopTableSize + sizeof(WORD) + sizeof(TRefineTable) * m_iRefineTableSize + sizeof(WORD) + sizeof(TItemAttrTable) * m_vec_itemAttrTable.size() + sizeof(WORD) + sizeof(TItemAttrTable) * m_vec_itemRareTable.size(); and change it like this tmp->EncodeHeader(HEADER_DG_RELOAD_PROTO, 0, sizeof(WORD) + sizeof(TSkillTable) * m_vec_skillTable.size() + sizeof(WORD) + sizeof(TBanwordTable) * m_vec_banwordTable.size() + sizeof(WORD) + sizeof(TItemTable) * m_vec_itemTable.size() + sizeof(WORD) + sizeof(TMobTable) * m_vec_mobTable.size() + sizeof(WORD) + sizeof(TShopTable) * m_iShopTableSize + sizeof(WORD) + sizeof(TRefineTable) * m_iRefineTableSize + sizeof(WORD) + sizeof(TItemAttrTable) * m_vec_itemAttrTable.size() + sizeof(WORD) + sizeof(TItemAttrTable) * m_vec_itemRareTable.size() + sizeof(WORD) + sizeof(TItemAttrTable) * m_vec_costumeAttrTable.size()); look for peer->EncodeWORD(sizeof(TItemAttrTable)); peer->EncodeWORD(m_vec_itemRareTable.size()); peer->Encode(&m_vec_itemRareTable[0], sizeof(TItemAttrTable) * m_vec_itemRareTable.size()); add under peer->EncodeWORD(sizeof(TItemAttrTable)); peer->EncodeWORD(m_vec_costumeAttrTable.size()); peer->Encode(&m_vec_costumeAttrTable[0], sizeof(TItemAttrTable) * m_vec_costumeAttrTable.size()); open constants.cpp and look for TItemAttrMap g_map_itemRare; add under TItemAttrMap g_map_itemAttrCostume; open constants.h and look for extern TItemAttrMap g_map_itemRare; add under extern TItemAttrMap g_map_itemAttrCostume; open input_db.cpp and look for /* * ITEM RARE */ if (decode_2bytes(data) != sizeof(TItemAttrTable)) { sys_err("item rare table size error"); thecore_shutdown(); return; } data += 2; size = decode_2bytes(data); data += 2; sys_log(0, "BOOT: ITEM_RARE: %d", size); if (size) { TItemAttrTable * p = (TItemAttrTable *) data; for (int i = 0; i < size; ++i, ++p) { if (p->dwApplyIndex >= MAX_APPLY_NUM) continue; g_map_itemRare[p->dwApplyIndex] = *p; sys_log(0, "ITEM_RARE[%d]: %s %u", p->dwApplyIndex, p->szApply, p->dwProb); } } data += size * sizeof(TItemAttrTable); add under /* * ITEM ATTR COSTUME */ if (decode_2bytes(data) != sizeof(TItemAttrTable)) { sys_err("item attr costume table size error"); thecore_shutdown(); return; } data += 2; size = decode_2bytes(data); data += 2; sys_log(0, "BOOT: ITEM_ATTR_COSTUME: %d", size); if (size) { TItemAttrTable* p = (TItemAttrTable*)data; for (int i = 0; i < size; ++i, ++p) { if (p->dwApplyIndex >= MAX_APPLY_NUM) continue; g_map_itemAttrCostume[p->dwApplyIndex] = *p; sys_log(0, "ITEM_ATTR_COSTUME[%d]: %s %u", p->dwApplyIndex, p->szApply, p->dwProb); } } data += size * sizeof(TItemAttrTable); open item_attribute.cpp and add these functions at the end (I don't remember why I rewrote this part, just replace your functions if you already have them) bool CItem::AddCostumeAttribute() { int count = GetAttributeCount(); if (count >= COSTUME_ATTRIBUTE_MAX_LEVEL) return false; int pos = count; TPlayerItemAttribute& attr = m_aAttr[pos]; int nAttrSet = GetAttributeSetIndex(); std::vector<int> avail; for (int i = 0; i < MAX_APPLY_NUM; ++i) { const TItemAttrTable& r = g_map_itemAttrCostume[i]; if (r.dwApplyIndex != 0 && r.bMaxLevelBySet[nAttrSet] > 0 && HasAttr(i) != true) { avail.push_back(i); } } if (avail.size() == 0) { return false; } const TItemAttrTable& r = g_map_itemAttrCostume[avail[number(0, avail.size() - 1)]]; int nAttrLevel = number(1, 5); if (nAttrLevel > r.bMaxLevelBySet[nAttrSet]) nAttrLevel = r.bMaxLevelBySet[nAttrSet]; attr.bType = r.dwApplyIndex; attr.sValue = r.lValues[nAttrLevel - 1]; UpdatePacket(); Save(); return true; } bool CItem::AddRandomNumberOfCostumeAttributes() { int cnt = GetAttributeCount(); int new_bonus_cnt = number(1, 3); for (int i = 0; i < cnt; ++i) { m_aAttr[i].bType = 0; m_aAttr[i].sValue = 0; } for (int i = 0; i < new_bonus_cnt ; ++i) { AddCostumeAttribute(); } return true; } bool CItem::ChangeCostumeAttribute() { int cnt = GetAttributeCount(); for (int i = 0; i < cnt; ++i) { m_aAttr[i].bType = 0; m_aAttr[i].sValue = 0; } for (int i = 0; i < cnt; ++i) { AddCostumeAttribute(); } return true; } open item_length.h and look for ITEM_ATTRIBUTE_MAX_LEVEL = 5, add under COSTUME_ATTRIBUTE_MAX_LEVEL = 5, open item.h and look for int GetRareAttrCount(); bool AddRareAttribute(); add under bool AddCostumeAttribute(); bool ChangeCostumeAttribute(); bool AddRandomNumberOfCostumeAttributes(); open char_item.cpp and look for switch (item->GetSubType()) { case USE_CHANGE_COSTUME_ATTR: item2->ChangeAttribute(); { char buf[21]; snprintf(buf, sizeof(buf), "%u", item2->GetID()); LogManager::instance().ItemLog(this, item, "CHANGE_COSTUME_ATTR", buf); } break; case USE_RESET_COSTUME_ATTR: item2->ClearAttribute(); item2->AlterToMagicItem(); { char buf[21]; snprintf(buf, sizeof(buf), "%u", item2->GetID()); LogManager::instance().ItemLog(this, item, "RESET_COSTUME_ATTR", buf); } break; } ChatPacket(CHAT_TYPE_INFO, LC_TEXT("¼Ó¼ºÀ» º¯°æÇÏ¿´½À´Ï´Ù.")); item->SetCount(item->GetCount() - 1); break; replace with if (item->GetSubType() == USE_RESET_COSTUME_ATTR) { if (item2->GetAttributeCount() < 3) { if (item2->AddCostumeAttribute()) { item->SetCount(item->GetCount() - 1); } } } else { if (item2->GetAttributeCount() == 0) { ChatPacket(CHAT_TYPE_INFO, "You must add some bonuses first."); return false; } if (item2->ChangeCostumeAttribute()) { item->SetCount(item->GetCount() - 1); } } break; run this query in your database player: DROP TABLE IF EXISTS `item_attr_costume`; CREATE TABLE `item_attr_costume` ( `apply` enum('MAX_HP','MAX_SP','CON','INT','STR','DEX','ATT_SPEED','MOV_SPEED','CAST_SPEED','HP_REGEN','SP_REGEN','POISON_PCT','STUN_PCT','SLOW_PCT','CRITICAL_PCT','PENETRATE_PCT','ATTBONUS_HUMAN','ATTBONUS_ANIMAL','ATTBONUS_ORC','ATTBONUS_MILGYO','ATTBONUS_UNDEAD','ATTBONUS_DEVIL','STEAL_HP','STEAL_SP','MANA_BURN_PCT','DAMAGE_SP_RECOVER','BLOCK','DODGE','RESIST_SWORD','RESIST_TWOHAND','RESIST_DAGGER','RESIST_BELL','RESIST_FAN','RESIST_BOW','RESIST_FIRE','RESIST_ELEC','RESIST_MAGIC','RESIST_WIND','REFLECT_MELEE','REFLECT_CURSE','POISON_REDUCE','KILL_SP_RECOVER','EXP_DOUBLE_BONUS','GOLD_DOUBLE_BONUS','ITEM_DROP_BONUS','POTION_BONUS','KILL_HP_RECOVER','IMMUNE_STUN','IMMUNE_SLOW','IMMUNE_FALL','SKILL','BOW_DISTANCE','ATT_GRADE_BONUS','DEF_GRADE_BONUS','MAGIC_ATT_GRADE_BONUS','MAGIC_DEF_GRADE_BONUS','CURSE_PCT','MAX_STAMINA','ATT_BONUS_TO_WARRIOR','ATT_BONUS_TO_ASSASSIN','ATT_BONUS_TO_SURA','ATT_BONUS_TO_SHAMAN','ATT_BONUS_TO_MONSTER','ATT_BONUS','MALL_DEFBONUS','MALL_EXPBONUS','MALL_ITEMBONUS','MALL_GOLDBONUS','MAX_HP_PCT','MAX_SP_PCT','SKILL_DAMAGE_BONUS','NORMAL_HIT_DAMAGE_BONUS','SKILL_DEFEND_BONUS','NORMAL_HIT_DEFEND_BONUS','PC_BANG_EXP_BONUS','PC_BANG_DROP_BONUS','EXTRACT_HP_PCT','RESIST_WARRIOR','RESIST_ASSASSIN','RESIST_SURA','RESIST_SHAMAN','ENERGY','DEF_GRADE','COSTUME_ATTR_BONUS','MAGIC_ATT_BONUS_PER','MELEE_MAGIC_ATT_BONUS_PER','RESIST_ICE','RESIST_EARTH','RESIST_DARK','RESIST_CRITICAL','RESIST_PENETRATE','BLEEDING_REDUCE','BLEEDING_PCT','ATT_BONUS_TO_WOLFMAN','RESIST_WOLFMAN','RESIST_CLAW') NOT NULL DEFAULT 'MAX_HP', `prob` int unsigned NOT NULL DEFAULT '0', `lv1` int unsigned NOT NULL DEFAULT '0', `lv2` int unsigned NOT NULL DEFAULT '0', `lv3` int unsigned NOT NULL DEFAULT '0', `lv4` int unsigned NOT NULL DEFAULT '0', `lv5` int unsigned NOT NULL DEFAULT '0', `weapon` int unsigned NOT NULL DEFAULT '0', `body` int unsigned NOT NULL DEFAULT '0', `wrist` int unsigned NOT NULL DEFAULT '0', `foots` int unsigned NOT NULL DEFAULT '0', `neck` int unsigned NOT NULL DEFAULT '0', `head` int unsigned NOT NULL DEFAULT '0', `shield` int unsigned NOT NULL DEFAULT '0', `ear` int unsigned NOT NULL DEFAULT '0', `costume_body` int unsigned NOT NULL DEFAULT '0', `costume_hair` int unsigned NOT NULL DEFAULT '0', `costume_weapon` int unsigned NOT NULL DEFAULT '0' ) ENGINE=MyISAM DEFAULT CHARSET=latin1; SET FOREIGN_KEY_CHECKS=1; and you can add bonuses you want for costumes in it that's it
  12. There was another similar system that had a bug: when you have the full ds set and you summon/unsummon a pet, the ds set will not give you the additional bonus have you tested this scenario?
  13. I usually retain log for 1-2 weeks, plus storage is cheap, time not.... so Of course if you do not clear your logs for years it's gonna take much space
  14. Some files have this problem: if you absorb an item on the sash, base bonuses of that item will not be applied. The fix is quite simple. Open item.cpp and look for long value = m_pProto->aApplies[i].lValue; replace it with BYTE bType = m_pProto->aApplies[i].bType; long value = m_pProto->aApplies[i].lValue; inside the #ifdef below, find if (pkItemAbsorbed->aApplies[i].bType == APPLY_NONE) continue; value = pkItemAbsorbed->aApplies[i].lValue; if (value < 0) continue; and relpace with if (pkItemAbsorbed->aApplies[i].bType == APPLY_NONE) continue; value = pkItemAbsorbed->aApplies[i].lValue; bType = pkItemAbsorbed->aApplies[i].bType; if (value < 0) continue; under find if (0 != accessoryGrade) value += MAX(accessoryGrade, value * aiAccessorySocketEffectivePct[accessoryGrade] / 100); m_pOwner->ApplyPoint(m_pProto->aApplies[i].bType, bAdd ? value : -value); and replace with if (0 != accessoryGrade) value += MAX(accessoryGrade, value * aiAccessorySocketEffectivePct[accessoryGrade] / 100); m_pOwner->ApplyPoint(bType, bAdd ? value : -value); done
  15. Sometimes you have to search for someting on the "log" table in the database "log", but when you have many records the search will take much time. Why this happens? There are no index on that table, I don't know why anyone didn't add indexes to that table. Indexes take space on your hard disk, they can take even gigabytes but... why do you have a log table if you can't look up for anything because it takes so much time to filter rows? We add some indexes to that table running this query inside the database "log": ALTER TABLE `log` ADD INDEX `who_index` (`who`) USING BTREE , ADD INDEX `time_index` (`time`) USING BTREE , ADD INDEX `how_index` (`how`) USING HASH , ADD INDEX `vnum_index` (`vnum`) USING BTREE ; It can take some time to build these indexes. If it takes too long, you probably should truncate the log table and then create the index.
  16. What is your budget? I suggest getting a vps + free direct admin license from buyshared o nexusbytes
  17. You have to edit the source for this. Make the experience ring stackable by changing the item flag Edit the source code to only use a single exp ring if stack > 1. if you click on the whole stack it will wear the whole stack of experience rings
  18. Use gdb to debug the game.core file and post here the debug info
×
×
  • 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.