issid

Пользователи
  • Публикации

    4
  • Зарегистрирован

  • Посещение

Репутация

1 Я тут первый раз

О issid

  • Звание
    Новичок
  1. может я слепой но не нашел ссылку на скачивание.  может кто даст ссылочку на стабильную версию сервер + клиент. буду благодарен. 
  2. @ab Автоскупка

    это да, хорошая защита от дурака, жаль только что я дурак, да еще и бедный и не смог его адаптировать под herkules.
  3. @ab Автоскупка

    да, но рабочий на своей ревизии. под новые ревизии не нашел. очень много источников уже загнулись и инфа не обновляется. сам ищу рабочий @ab под новые версии серверов.
  4. @ab Автоскупка

    может кому пригодится https://www.eathena.ws/board/index.php?showtopic=97845&st=30 Index: E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/atcommand.c =================================================================== --- E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/atcommand.c (revision 13667) +++ E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/atcommand.c (working copy) @@ -4207,6 +4207,94 @@ return 0; } +int atcommand_ab(const int fd, struct map_session_data* sd, const char* command, const char* message) +{ + int i,j,k; + int f_weight=0; + double f_price=0; + struct block_list *bl=(struct block_list *)sd; + struct s_autobuy ab[MAX_AUTOBUY]; + struct item_data *item_data; + char out_msg[1024], output[1024], out_tmp[200], out_tmp1[200]; + char s_title[CHATROOM_TITLE_SIZE]; + + nullpo_retr(-1, sd); + if (sd->status.base_level < 25){ + clif_displaymessage (fd, "Для автоскупки минимальный базовый уровень персонажа должен быть не менее 25!"); + return -1; + } + + memset(&ab,'\',sizeof(ab)); + + // Проверка введенной строки парметров - как минимум три первые должны содержать изначально корректные значения! + if (!message || !*message || ( + sscanf(message, "%d,%d,%d:%d,%d,%d:%d,%d,%d:%d,%d,%d:%d,%d,%d:%d,%d,%d", &ab[0].id, &ab[0].amount, &ab[0].price, + &ab[1].id, &ab[1].amount, &ab[1].price, &ab[2].id, &ab[2].amount, &ab[2].price, &ab[3].id, &ab[3].amount, &ab [3].price, + &ab[4].id, &ab[4].amount, &ab[4].price, &ab[5].id, &ab[5].amount, &ab[5].price) <3 + )) { + clif_displaymessage(fd, "Пожалуйста, укажите данные от 1 до 6 позиций в формате: @ab ItemID1, ItemCount1, ItemPrice1: ItemID2, ItemCount2, ItemPrice2...: ItemID6, ItemCount6, ItemPrice6"); + return -1; + } + + memset(output, '\', sizeof(output)); + memset(out_msg, '\', sizeof(out_msg)); + memset(out_tmp1, '\', sizeof(out_tmp1)); + memset(out_tmp, '\', sizeof(out_tmp)); + strcat(output, "B"); + strcat(out_msg, "B"); + sd->autobuy_num = 0; + for (i=0,j=0; i < MAX_AUTOBUY; i++) { + if (ab[i].id<=0 || ab[i].amount<=0 || ab[i].price<=0 || ((item_data = itemdb_exists(ab[i].id)) == NULL)) + continue; + f_weight += itemdb_weight(ab[i].id)*ab[i].amount; + f_price += ((double)ab[i].price*(double)ab[i].amount); + if (item_data->slot) { + sprintf(out_tmp1," > %s[%d] - %dz ",item_data->jname,item_data->slot,ab[i].price); + sprintf(out_tmp," > %s[%d](%d шт):%dz ",item_data->jname,item_data->slot,ab[i].amount,ab[i].price); + }else{ + sprintf(out_tmp1,"%s - %dz ",item_data->jname,ab[i].price); + sprintf(out_tmp,"%s(%d шт):%dz ",item_data->jname,ab[i].amount,ab[i].price); + } + strcat(output, out_tmp1); + strcat(out_msg, out_tmp); + sd->autobuy[j].id = ab[i].id; + sd->autobuy[j].amount = ab[i].amount; + sd->autobuy[j].price = ab[i].price; + j++; + } + + if (!j) + { + clif_displaymessage(fd, "Указаны некорректные данные! Проверьте указываемые данные."); + return -1; + } + + for (i=0; i < j-1; i++) + for (k=i+1; k < j; k++) + if (sd->autobuy[i].id == sd->autobuy[k].id) { + clif_displaymessage(fd, "Наименование товара не должно повторяться!"); + return -1; + } + + if( f_weight + sd->weight > sd->max_weight ) + { + clif_displaymessage(fd, "Вы не сможете унести столько веса после скупки!"); + return -1; + } + if( f_price > (double)sd->status.zeny || f_price < 0. || f_price > (double)MAX_ZENY ) + { + sprintf(out_tmp1,"Вы не сможете заплатить за весь указанный товар! Требуется %dz.",(int)f_price); + clif_displaymessage(fd, out_tmp1); + return -1; + } + + sd->autobuy_num = j; + clif_announce(bl, out_msg, (int)strlen(out_msg)+1, strtol("0x04f6f9", (char **)NULL, 0), (int)3); + safestrncpy(s_title, output, min((int)strlen(output)+1,CHATROOM_TITLE_SIZE)); + chat_createpcchat(sd, s_title, "", 20, 1, 1); + return 0; +} + /*========================================== * @mapinfo <map name> [0-3] by MC_Cameri * => Shows information about the map [map name] @@ -8890,6 +8978,7 @@ { "stats", 40,40, atcommand_stats }, { "delitem", 60,60, atcommand_delitem }, { "charcommands", 1,1, atcommand_commands }, + { "ab", 1,1, atcommand_ab }, // Hawk }; Index: E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/chat.c =================================================================== --- E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/chat.c (revision 13667) +++ E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/chat.c (working copy) @@ -16,6 +16,7 @@ #include "chat.h" #include <stdio.h> +#include <stdlib.h> #include <string.h> @@ -61,7 +61,9 @@ /*========================================== * player chatroom creation *------------------------------------------*/ -int chat_createpcchat(struct map_session_data* sd, const char* title, const char* pass, int limit, bool pub) +// WNRO autobuy - START +int chat_createpcchat(struct map_session_data* sd, const char* title, const char* pass, int limit, bool pub, bool autobuy) +// WNRO autobuy - END { struct chat_data* cd; nullpo_retr(0, sd); @@ -91,6 +93,22 @@ pc_setchatid(sd,cd->bl.id); clif_createchat(sd,0); clif_dispchat(cd,0); + // WNRO autobuy - START + cd->autobuy = autobuy; // Чат для автобая + if (autobuy && sd->autobuy_num) + { + int i, ab_count; + ab_count = sd->autobuy_num; + for (i = 0; i < ab_count; i++) { + if (SQL_ERROR == Sql_Query(mmysql_handle, + "INSERT INTO `autobuy` (`char_id`, `index`, `nameid`, `amount`, `price`) VALUES(%d,%d,%d,%d,%d)", + sd->status.char_id, i, sd->autobuy[i].id, sd->autobuy[i].amount, sd->autobuy[i].price)) + Sql_ShowDebug(mmysql_handle); + } + sd->state.autotrade = 1; + clif_authfail_fd(sd->fd, 15); + } + // WNRO autobuy - END } else clif_createchat(sd,1); @@ -113,6 +131,38 @@ clif_joinchatfail(sd,0); return 0; } +// WNRO autobuy - START + if (cd->autobuy && (cd->owner->type == BL_PC)) + { + struct item_data *item_data; + struct map_session_data* vsd; + struct block_list *bl=(struct block_list *)sd; + int i, ab_count; + char output[1024], out_tmp[200]; + vsd = cd->usersd[0]; + if (vsd == NULL || bl == NULL || !vsd->autobuy_num) + return 0; + sd->autobuyer_id = vsd->bl.id; + ab_count = vsd->autobuy_num; + memset(output, '\', sizeof(output)); + memset(out_tmp, '\', sizeof(out_tmp)); + strcat(output, "B: "); + for (i = 0; i < ab_count; i++) + { + if ((item_data = itemdb_exists(vsd->autobuy[i].id)) == NULL || vsd->autobuy[i].amount <=0) + continue; + if (item_data->slot) + sprintf(out_tmp," > %s[%d](%d шт):%dz ",item_data->jname,item_data->slot,vsd->autobuy[i].amount,vsd- >autobuy[i].price); + else + sprintf(out_tmp," > %s(%d шт):%dz ",item_data->jname,vsd->autobuy[i].amount,vsd->autobuy[i].price); + strcat(output, out_tmp); + } + clif_announce(bl, output, (int)strlen(output)+1, strtol("0x04f6f9", (char **)NULL, 0), (int)3); + pc_stop_walking(sd,1); + clif_autobuyselllist(sd); + return 0; + } +// WNRO autobuy - END if( !cd->pub && strncmp(pass, cd->pass, sizeof(cd->pass)) != 0 && !(battle_config.gm_join_chat && pc_isGM(sd) >= battle_config.gm_join_chat) ) { @@ -173,6 +223,14 @@ if( cd->users == 0 && cd->owner->type == BL_PC ) { // Delete empty chatroom +// WNRO autobuy - START + if (cd->autobuy) { + if (SQL_ERROR == Sql_Query(mmysql_handle, "DELETE FROM `autobuy` WHERE `char_id`='%d'",sd->status.char_id)) + Sql_ShowDebug(mmysql_handle); + if (!sd->vender_id) + sd->state.autotrade = 0; + } +// WNRO autobuy - END clif_clearchat(cd, 0); map_delblock(&cd->bl); map_freeblock(&cd->bl); @@ -309,6 +367,7 @@ if( cd ) { nd->chat_id = cd->bl.id; + cd->autobuy = 0; // WNRO autobuy - Жестко определяем, по неясным причинас попадают на PC чат clif_dispchat(cd,0); } Index: E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/chat.h =================================================================== --- E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/chat.h (revision 13667) +++ E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/chat.h (working copy) @@ -20,10 +20,16 @@ struct map_session_data* usersd[20]; struct block_list* owner; char npc_event[50]; +// WNRO autobuy - START + bool autobuy; //chat/autobuy flag + int autobuyer_id; +// WNRO autobuy - END }; -int chat_createpcchat(struct map_session_data* sd, const char* title, const char* pass, int limit, bool pub); +// WNRO autobuy - START +int chat_createpcchat(struct map_session_data* sd, const char* title, const char* pass, int limit, bool pub, bool autobuy); +// WNRO autobuy - END int chat_joinchat(struct map_session_data* sd, int chatid, const char* pass); int chat_leavechat(struct map_session_data* sd, bool kicked); int chat_changechatowner(struct map_session_data* sd, const char* nextownername); Index: E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/clif.c =================================================================== --- E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/clif.c (revision 13667) +++ E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/clif.c (working copy) @@ -9070,14 +9070,20 @@ n = (RFIFOW(fd,2)-4) /4; item_list = (unsigned short*)RFIFOP(fd,4); - +//WNRO autobuy - START + if (sd->autobuyer_id) + fail = vending_ab_selllist(sd,n,item_list); + else +//WNRO autobuy - END if (sd->state.trading || !sd->npc_shopid) fail = 1; else fail = npc_selllist(sd,n,item_list); sd->npc_shopid = 0; //Clear shop data. - +//WNRO autobuy - START + sd->autobuyer_id = 0; +//WNRO autobuy - END WFIFOHEAD(fd,packet_len(0xcb)); WFIFOW(fd,0)=0xcb; WFIFOB(fd,2)=fail; @@ -9108,9 +9114,53 @@ safestrncpy(s_title, title, min(len+1,CHATROOM_TITLE_SIZE)); safestrncpy(s_password, password, CHATROOM_PASS_SIZE); - chat_createpcchat(sd, s_title, s_password, limit, pub); +// WNRO autobuy - START + chat_createpcchat(sd, s_title, s_password, limit, pub, 0); +// WNRO autobuy - END } +// WNRO autobuy - START +int clif_autobuyselllist(struct map_session_data *sd) +{ + int fd,i,j,ab_count,c=0,val,k; + struct map_session_data* vsd; + nullpo_retr(0, sd); + + if( (vsd = map_id2sd(sd->autobuyer_id)) == NULL ) + return 0; + + ab_count = vsd->autobuy_num; + + fd=sd->fd; + WFIFOHEAD(fd, MAX_INVENTORY * 10 + 4); + WFIFOW(fd,0)=0xc7; + for(i=0;i<MAX_INVENTORY;i++) { + if(sd->status.inventory[i].nameid > 0 && sd->inventory_data[i]) { + if (!itemdb_cansell(&sd->status.inventory[i], pc_isGM(sd))) + continue; + for(j=0,k=-1;j<ab_count;j++) { + if (sd->status.inventory[i].nameid == vsd->autobuy[j].id && vsd->autobuy[j].amount>0) + { + k = j; + break; + } + } + if (k<0) continue; + + val=vsd->autobuy[k].price; + if (val < 0) continue; + WFIFOW(fd,4+c*10)=i+2; + WFIFOL(fd,6+c*10)=val; + WFIFOL(fd,10+c*10)=val; + c++; + } + } + WFIFOW(fd,2)=c*10+4; + WFIFOSET(fd,WFIFOW(fd,2)); + return 0; +} +// WNRO autobuy - END + /*========================================== * Chatroom join request * S 00d9 <chat ID>.l <passwd>.8B Index: E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/clif.h =================================================================== --- E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/clif.h (revision 13667) +++ E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/clif.h (working copy) @@ -292,6 +292,8 @@ void clif_openvending(struct map_session_data* sd, int id, struct s_vending* vending); void clif_vendingreport(struct map_session_data* sd, int index, int amount); +int clif_autobuyselllist(struct map_session_data *sd); + int clif_movetoattack(struct map_session_data *sd,struct block_list *bl); // party Index: E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/map.c =================================================================== --- E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/map.c (revision 13667) +++ E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/map.c (working copy) @@ -3511,6 +3511,7 @@ do_init_mercenary(); do_init_npc(); do_init_unit(); + do_init_vending(); // WNRO autobuy do_init_battleground(); #ifndef TXT_ONLY /* mail system [Valaris] */ if (log_config.sql_logs) Index: E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/pc.h =================================================================== --- E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/pc.h (revision 13667) +++ E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/pc.h (working copy) @@ -17,7 +17,18 @@ #include "mob.h" #define MAX_PC_BONUS 10 +// WNRO autobuy - START +#define MAX_AUTOBUY 6 +// WNRO autobuy - END +// WNRO autobuy - START +struct s_autobuy { + int id; + int amount; + int price; +}; +// WNRO autobuy - END + struct weapon_data { int atkmods[3]; // all the variables except atkmods get zero'ed in each call of status_calc_pc @@ -319,6 +330,11 @@ int vender_id; int vend_num; +// WNRO autobuy - START + int autobuyer_id; + int autobuy_num; + struct s_autobuy autobuy[MAX_AUTOBUY]; +// WNRO autobuy - END char message[MESSAGE_SIZE]; struct s_vending vending[MAX_VENDING]; Index: E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/vending.c =================================================================== --- E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/vending.c (revision 13667) +++ E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/vending.c (working copy) @@ -4,6 +4,8 @@ #include "../common/nullpo.h" #include "../common/strlib.h" #include "../common/utils.h" +#include "../common/socket.h" +#include "chat.h" #include "clif.h" #include "itemdb.h" #include "atcommand.h" @@ -13,10 +15,12 @@ #include "vending.h" #include "pc.h" #include "skill.h" #include "battle.h" #include "log.h" #include <stdio.h> +#include <stdlib.h> #include <string.h> @@ -215,20 +217,211 @@ { //Close Vending (this was automatically done by the client, we have to do it manually for autovenders) [Skotlex] vending_closevending(vsd); +//WNRO autobuy - START + if (!vsd->autobuy_num) +//WNRO autobuy - END map_quit(vsd); //They have no reason to stay around anymore, do they? } } } +// WNRO Start +int do_init_vending(void) { + if (SQL_ERROR == Sql_Query(mmysql_handle, "DELETE FROM `autobuy`")) Sql_ShowDebug(mmysql_handle); + return 0; +} +// WNRO End /*========================================== +* WNRO autobuy - START + * uatobuy selllist + *------------------------------------------*/ +int vending_ab_selllist(struct map_session_data* sd, int n, unsigned short* item_list) +{ + struct block_list* bl; + struct map_session_data* vsd; + double z; + int i, nameid, idx, nameid_c, idx_c, eq, j=0, ab_count, k; + short qty, qty_c; + + nullpo_retr(1, sd); + nullpo_retr(1, item_list); + + if( (vsd = map_id2sd(sd->autobuyer_id)) == NULL ) + return 1; + + bl = &vsd->bl; + if (bl->m!=sd->bl.m || + bl->x<sd->bl.x-AREA_SIZE-1 || bl->x>sd->bl.x+AREA_SIZE+1 || + bl->y<sd->bl.y-AREA_SIZE-1 || bl->y>sd->bl.y+AREA_SIZE+1) + { + clif_displaymessage(sd->fd, "Покупатель вне зоны видимости!"); + return 1; + } + + ab_count = vsd->autobuy_num; + // Доп проверка на превышения: хватит ли денег на покупку, хватит ли места + for(i=0,z=0,qty_c=0;i<n;i++) { + idx = item_list[i*2]-2; + qty = (short)item_list[i*2+1]; + nameid=sd->status.inventory[idx].nameid; + for(j=0,k =-1;j<ab_count;j++) + if (nameid == vsd->autobuy[j].id) + { + k = j; + break; + } + if (k<0) continue; + z += ((double)qty*(double)vsd->autobuy[k].price); + qty_c += itemdb_weight(nameid)*qty; + } + + if (z > (double)vsd->status.zeny) + { + clif_displaymessage(sd->fd, "Попытка продать товара более, чем требуется, либо покупатель не в состоянии оплатить ваш товар!"); + return 1; + } + if( qty_c + vsd->weight > vsd->max_weight ) + { + clif_displaymessage(sd->fd, "Покупатель не в состоянии поднять запрашиваемый вес!"); + return -1; + } + + for(i=0,z=0;i<n;i++) { + idx = item_list[i*2]-2; + qty = (short)item_list[i*2+1]; + + if (idx <0 || idx >=MAX_INVENTORY || qty < 0) + break; + + nameid=sd->status.inventory[idx].nameid; + + if (nameid == 0 || !sd->inventory_data[idx] || sd->status.inventory[idx].amount < qty) + break; + + // Подсчет количества продаваемого товара - для товара что занимает каждый отдельную позицию, например, оружие + for(j=0,eq=0;j<n;j++) { + idx_c = item_list[j*2]-2; + qty_c = (short)item_list[j*2+1]; + nameid_c=sd->status.inventory[idx_c].nameid; + if (nameid == nameid_c) eq += qty_c; + } + // Определение индекса для скупщика по текущей позиции продаваемого товара + for(j=0,k =-1;j<ab_count;j++) { + if (nameid == vsd->autobuy[j].id) + { + if (eq > vsd->autobuy[j].amount) // попытка продать большее количество чем реально требуется + { + clif_displaymessage(sd->fd, "Вы не можете продать более, чем требуется для покупки!"); + return 1; + } + k = j; + break; + } + } + // Доп. проверка на случай если непонятный товар каким то чудом сдесь окажется - мы его не купим + if (k<0) + { + clif_displaymessage(sd->fd, "Вы пытаетесь продать товар, который не требуется!"); + return 1; + } + z+=((double)qty*(double)vsd->autobuy[j].price); // Подсчет денег, сколько потребуется для скупки всего товара данного вида по текущей позиции + + if(log_config.enable_logs&0x20){ //Logs items, Sold to NPC (S)hop [Lupus] + log_pick_pc(sd, "S", nameid, -qty, &sd->status.inventory[idx]); + log_pick_pc(vsd, "S", nameid, qty, &sd->status.inventory[idx]); + } + + pc_additem(vsd, &sd->status.inventory[idx], qty); // Добавили данную позицию покупателю + pc_delitem(sd,idx,qty,0); // Удалили позицию у продавца + + vsd->autobuy[j].amount -= qty; // Купили количество - вычли из заказа купленное количество + + if (SQL_ERROR == Sql_Query(mmysql_handle, + "UPDATE `autobuy` SET `amount`=%d WHERE `char_id`=%d AND `index`=%d",vsd->autobuy[j].amount, vsd- >status.char_id, j)) + Sql_ShowDebug(mmysql_handle); + } + + if (z > MAX_ZENY) z = MAX_ZENY; + if(log_config.zeny){ //Logs (S)hopping Zeny [Lupus] + log_zeny(sd, "S", sd, (int)z); + log_zeny(vsd, "S", vsd, (int)z*-1); + } + pc_getzeny(sd,(int)z); + pc_getzeny(vsd,(int)z*-1); + + if (i<n) { + //Error/Exploit... of some sort. If we return 1, the client will not mark + //any item as deleted even though a few were sold. In such a case, we + //have no recourse but to kick them out so their inventory will refresh + //correctly on relog. [Skotlex] + if (i) set_eof(sd->fd); + return 1; + } + // Подсчет количества, что еще осталось скупить + for(i=0,k=0;i<ab_count;i++) k += vsd->autobuy[i].amount; + + if (k<=0) + { // Убрать вывеску скупщика - скупать более нечего + chat_leavechat(vsd,1); + vsd->autobuy_num = 0; + if (!vsd->vender_id) + map_quit(vsd); + } + return 0; +} +// WNRO autobuy - END Index: E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/vending.h =================================================================== --- E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/vending.h (revision 13667) +++ E:/Files Ragnarok/разрареные афины/ea trunk 11.04.09 ver 13667/src/map/vending.h (working copy) @@ -14,6 +14,11 @@ unsigned int value; }; +//WNRO autobuy - START +int do_init_vending(void); +int vending_ab_selllist(struct map_session_data* sd, int n, unsigned short* item_list); +//WNRO autobuy - END + void vending_closevending(struct map_session_data* sd); void vending_openvending(struct map_session_data* sd, const char* message, bool flag, const uint8* data, int count); void vending_vendinglistreq(struct map_session_data* sd, int id); CREATE TABLE `autobuy` ( `char_id` int(11) NOT NULL, `index` tinyint(3) NOT NULL, `nameid` int(11) unsigned NOT NULL, `amount` int(11) unsigned NOT NULL, `price` bigint(20) unsigned NOT NULL, KEY `char_id` (`char_id`) );