diff options
author | amber <amber@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2004-11-14 16:18:26 +0000 |
---|---|---|
committer | amber <amber@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2004-11-14 16:18:26 +0000 |
commit | 581475bc6416790765c498aa3d611f6868ffb64a (patch) | |
tree | 347ebf88eaa76e50488f23989d67cad834f3c9b1 /src/char/int_party.c | |
parent | 600362764ce348c5c9de96eababff2e08bb90d4a (diff) | |
download | hercules-581475bc6416790765c498aa3d611f6868ffb64a.tar.gz hercules-581475bc6416790765c498aa3d611f6868ffb64a.tar.bz2 hercules-581475bc6416790765c498aa3d611f6868ffb64a.tar.xz hercules-581475bc6416790765c498aa3d611f6868ffb64a.zip |
Fixed some file types
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/athena@172 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/char/int_party.c')
-rw-r--r-- | src/char/int_party.c | 1190 |
1 files changed, 595 insertions, 595 deletions
diff --git a/src/char/int_party.c b/src/char/int_party.c index 499ac025b..0fd58fa14 100644 --- a/src/char/int_party.c +++ b/src/char/int_party.c @@ -1,595 +1,595 @@ -// $Id: int_party.c,v 1.1.1.1 2004/09/10 17:26:51 MagicalTux Exp $
-#include "inter.h"
-#include "int_party.h"
-#include "mmo.h"
-#include "char.h"
-#include "socket.h"
-#include "db.h"
-#include "lock.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-char party_txt[1024] = "save/party.txt";
-
-static struct dbt *party_db;
-static int party_newid = 100;
-
-int mapif_party_broken(int party_id, int flag);
-int party_check_empty(struct party *p);
-int mapif_parse_PartyLeave(int fd, int party_id, int account_id);
-
-// パーティデータの文字列への変換
-int inter_party_tostr(char *str, struct party *p) {
- int i, len;
-
- len = sprintf(str, "%d\t%s\t%d,%d\t", p->party_id, p->name, p->exp, p->item);
- for(i = 0; i < MAX_PARTY; i++) {
- struct party_member *m = &p->member[i];
- len += sprintf(str + len, "%d,%d\t%s\t", m->account_id, m->leader, ((m->account_id > 0) ? m->name : "NoMember"));
- }
-
- return 0;
-}
-
-// パーティデータの文字列からの変換
-int inter_party_fromstr(char *str, struct party *p) {
- int i, j;
- int tmp_int[16];
- char tmp_str[256];
-
- memset(p, 0, sizeof(struct party));
-
-// printf("sscanf party main info\n");
- if (sscanf(str, "%d\t%[^\t]\t%d,%d\t", &tmp_int[0], tmp_str, &tmp_int[1], &tmp_int[2]) != 4)
- return 1;
-
- p->party_id = tmp_int[0];
- strcpy(p->name, tmp_str);
- p->exp = tmp_int[1];
- p->item = tmp_int[2];
-// printf("%d [%s] %d %d\n", tmp_int[0], tmp_str[0], tmp_int[1], tmp_int[2]);
-
- for(j = 0; j < 3 && str != NULL; j++)
- str = strchr(str + 1, '\t');
-
- for(i = 0; i < MAX_PARTY; i++) {
- struct party_member *m = &p->member[i];
- if (str == NULL)
- return 1;
-// printf("sscanf party member info %d\n", i);
-
- if (sscanf(str + 1, "%d,%d\t%[^\t]\t", &tmp_int[0], &tmp_int[1], tmp_str) != 3)
- return 1;
-
- m->account_id = tmp_int[0];
- m->leader = tmp_int[1];
- strncpy(m->name, tmp_str, sizeof(m->name));
-// printf(" %d %d [%s]\n", tmp_int[0], tmp_int[1], tmp_str);
-
- for(j = 0; j < 2 && str != NULL; j++)
- str = strchr(str + 1, '\t');
- }
-
- return 0;
-}
-
-// パーティデータのロード
-int inter_party_init() {
- char line[8192];
- struct party *p;
- FILE *fp;
- int c = 0;
- int i, j;
-
- party_db = numdb_init();
-
- if ((fp = fopen(party_txt, "r")) == NULL)
- return 1;
-
- while(fgets(line, sizeof(line) - 1, fp)) {
- j = 0;
- if (sscanf(line, "%d\t%%newid%%\n%n", &i, &j) == 1 && j > 0 && party_newid <= i) {
- party_newid = i;
- continue;
- }
-
- p = calloc(sizeof(struct party), 1);
- if (p == NULL){
- printf("int_party: out of memory!\n");
- exit(0);
- }
- memset(p, 0, sizeof(struct party));
- if (inter_party_fromstr(line, p) == 0 && p->party_id > 0) {
- if (p->party_id >= party_newid)
- party_newid = p->party_id + 1;
- numdb_insert(party_db, p->party_id, p);
- party_check_empty(p);
- } else {
- printf("int_party: broken data [%s] line %d\n", party_txt, c + 1);
- free(p);
- }
- c++;
- }
- fclose(fp);
-// printf("int_party: %s read done (%d parties)\n", party_txt, c);
-
- return 0;
-}
-
-// パーティーデータのセーブ用
-int inter_party_save_sub(void *key, void *data, va_list ap) {
- char line[8192];
- FILE *fp;
-
- inter_party_tostr(line, (struct party *)data);
- fp = va_arg(ap, FILE *);
- fprintf(fp, "%s" RETCODE, line);
-
- return 0;
-}
-
-// パーティーデータのセーブ
-int inter_party_save() {
- FILE *fp;
- int lock;
-
- if ((fp = lock_fopen(party_txt, &lock)) == NULL) {
- printf("int_party: cant write [%s] !!! data is lost !!!\n", party_txt);
- return 1;
- }
- numdb_foreach(party_db, inter_party_save_sub, fp);
-// fprintf(fp, "%d\t%%newid%%\n", party_newid);
- lock_fclose(fp,party_txt, &lock);
-// printf("int_party: %s saved.\n", party_txt);
-
- return 0;
-}
-
-// パーティ名検索用
-int search_partyname_sub(void *key,void *data,va_list ap) {
- struct party *p = (struct party *)data,**dst;
- char *str;
-
- str = va_arg(ap, char *);
- dst = va_arg(ap, struct party **);
- if (strcmpi(p->name, str) == 0)
- *dst = p;
-
- return 0;
-}
-
-// パーティ名検索
-struct party* search_partyname(char *str) {
- struct party *p = NULL;
- numdb_foreach(party_db, search_partyname_sub, str, &p);
-
- return p;
-}
-
-// EXP公平分配できるかチェック
-int party_check_exp_share(struct party *p) {
- int i;
- int maxlv = 0, minlv = 0x7fffffff;
-
- for(i = 0; i < MAX_PARTY; i++) {
- int lv = p->member[i].lv;
- if (p->member[i].online) {
- if (lv < minlv)
- minlv = lv;
- if (maxlv < lv)
- maxlv = lv;
- }
- }
-
- return (maxlv == 0 || maxlv-minlv <= party_share_level);
-}
-
-// パーティが空かどうかチェック
-int party_check_empty(struct party *p) {
- int i;
-
-// printf("party check empty %08X\n", (int)p);
- for(i = 0; i < MAX_PARTY; i++) {
-// printf("%d acc=%d\n", i, p->member[i].account_id);
- if (p->member[i].account_id > 0) {
- return 0;
- }
- }
- // 誰もいないので解散
- mapif_party_broken(p->party_id, 0);
- numdb_erase(party_db, p->party_id);
- free(p);
-
- return 1;
-}
-
-// キャラの競合がないかチェック用
-int party_check_conflict_sub(void *key, void *data, va_list ap) {
- struct party *p = (struct party *)data;
- int party_id, account_id, i;
- char *nick;
-
- party_id=va_arg(ap, int);
- account_id=va_arg(ap, int);
- nick=va_arg(ap, char *);
-
- if (p->party_id == party_id) // 本来の所属なので問題なし
- return 0;
-
- for(i = 0; i < MAX_PARTY; i++) {
- if (p->member[i].account_id == account_id && strcmp(p->member[i].name, nick) == 0) {
- // 別のパーティに偽の所属データがあるので脱退
- printf("int_party: party conflict! %d %d %d\n", account_id, party_id, p->party_id);
- mapif_parse_PartyLeave(-1, p->party_id, account_id);
- }
- }
-
- return 0;
-}
-
-// キャラの競合がないかチェック
-int party_check_conflict(int party_id, int account_id, char *nick) {
- numdb_foreach(party_db, party_check_conflict_sub, party_id, account_id, nick);
-
- return 0;
-}
-
-//-------------------------------------------------------------------
-// map serverへの通信
-
-// パーティ作成可否
-int mapif_party_created(int fd,int account_id, struct party *p) {
- WFIFOW(fd,0) = 0x3820;
- WFIFOL(fd,2) = account_id;
- if (p != NULL) {
- WFIFOB(fd,6) = 0;
- WFIFOL(fd,7) = p->party_id;
- memcpy(WFIFOP(fd,11), p->name, 24);
- printf("int_party: created! %d %s\n", p->party_id, p->name);
- } else {
- WFIFOB(fd,6) = 1;
- WFIFOL(fd,7) = 0;
- memcpy(WFIFOP(fd,11), "error", 24);
- }
- WFIFOSET(fd,35);
-
- return 0;
-}
-
-// パーティ情報見つからず
-int mapif_party_noinfo(int fd, int party_id) {
- WFIFOW(fd,0) = 0x3821;
- WFIFOW(fd,2) = 8;
- WFIFOL(fd,4) = party_id;
- WFIFOSET(fd,8);
- printf("int_party: info not found %d\n", party_id);
-
- return 0;
-}
-
-// パーティ情報まとめ送り
-int mapif_party_info(int fd, struct party *p) {
- unsigned char buf[4 + sizeof(struct party)];
-
- WBUFW(buf,0) = 0x3821;
- memcpy(buf + 4, p, sizeof(struct party));
- WBUFW(buf,2) = 4 + sizeof(struct party);
- if (fd < 0)
- mapif_sendall(buf, WBUFW(buf,2));
- else
- mapif_send(fd, buf, WBUFW(buf,2));
-// printf("int_party: info %d %s\n", p->party_id, p->name);
-
- return 0;
-}
-
-// パーティメンバ追加可否
-int mapif_party_memberadded(int fd, int party_id, int account_id, int flag) {
- WFIFOW(fd,0) = 0x3822;
- WFIFOL(fd,2) = party_id;
- WFIFOL(fd,6) = account_id;
- WFIFOB(fd,10) = flag;
- WFIFOSET(fd,11);
-
- return 0;
-}
-
-// パーティ設定変更通知
-int mapif_party_optionchanged(int fd,struct party *p, int account_id, int flag) {
- unsigned char buf[15];
-
- WBUFW(buf,0) = 0x3823;
- WBUFL(buf,2) = p->party_id;
- WBUFL(buf,6) = account_id;
- WBUFW(buf,10) = p->exp;
- WBUFW(buf,12) = p->item;
- WBUFB(buf,14) = flag;
- if (flag == 0)
- mapif_sendall(buf, 15);
- else
- mapif_send(fd, buf, 15);
- printf("int_party: option changed %d %d %d %d %d\n", p->party_id, account_id, p->exp, p->item, flag);
-
- return 0;
-}
-
-// パーティ脱退通知
-int mapif_party_leaved(int party_id,int account_id, char *name) {
- unsigned char buf[34];
-
- WBUFW(buf,0) = 0x3824;
- WBUFL(buf,2) = party_id;
- WBUFL(buf,6) = account_id;
- memcpy(WBUFP(buf,10), name, 24);
- mapif_sendall(buf, 34);
- printf("int_party: party leaved %d %d %s\n", party_id, account_id, name);
-
- return 0;
-}
-
-// パーティマップ更新通知
-int mapif_party_membermoved(struct party *p, int idx) {
- unsigned char buf[29];
-
- WBUFW(buf,0) = 0x3825;
- WBUFL(buf,2) = p->party_id;
- WBUFL(buf,6) = p->member[idx].account_id;
- memcpy(WBUFP(buf,10), p->member[idx].map, 16);
- WBUFB(buf,26) = p->member[idx].online;
- WBUFW(buf,27) = p->member[idx].lv;
- mapif_sendall(buf, 29);
-
- return 0;
-}
-
-// パーティ解散通知
-int mapif_party_broken(int party_id, int flag) {
- unsigned char buf[7];
- WBUFW(buf,0) = 0x3826;
- WBUFL(buf,2) = party_id;
- WBUFB(buf,6) = flag;
- mapif_sendall(buf, 7);
- printf("int_party: broken %d\n", party_id);
-
- return 0;
-}
-
-// パーティ内発言
-int mapif_party_message(int party_id, int account_id, char *mes, int len) {
- unsigned char buf[len+12];
-
- WBUFW(buf,0) = 0x3827;
- WBUFW(buf,2) = len + 12;
- WBUFL(buf,4) = party_id;
- WBUFL(buf,8) = account_id;
- memcpy(WBUFP(buf,12), mes, len);
- mapif_sendall(buf,len + 12);
-
- return 0;
-}
-
-//-------------------------------------------------------------------
-// map serverからの通信
-
-
-// パーティ
-int mapif_parse_CreateParty(int fd, int account_id, char *name, char *nick, char *map, int lv) {
- struct party *p;
- int i;
-
- for(i = 0; i < 24 && name[i]; i++) {
- if (!(name[i] & 0xe0) || name[i] == 0x7f) {
- printf("int_party: illegal party name [%s]\n", name);
- mapif_party_created(fd, account_id, NULL);
- return 0;
- }
- }
-
- if ((p = search_partyname(name)) != NULL) {
- printf("int_party: same name party exists [%s]\n", name);
- mapif_party_created(fd, account_id, NULL);
- return 0;
- }
- p = calloc(sizeof(struct party), 1);
- if (p == NULL) {
- printf("int_party: out of memory !\n");
- mapif_party_created(fd,account_id,NULL);
- return 0;
- }
- memset(p, 0, sizeof(struct party));
- p->party_id = party_newid++;
- memcpy(p->name, name, 24);
- p->exp = 0;
- p->item = 0;
- p->member[0].account_id = account_id;
- memcpy(p->member[0].name, nick, 24);
- memcpy(p->member[0].map, map, 16);
- p->member[0].leader = 1;
- p->member[0].online = 1;
- p->member[0].lv = lv;
-
- numdb_insert(party_db, p->party_id, p);
-
- mapif_party_created(fd, account_id, p);
- mapif_party_info(fd, p);
-
- return 0;
-}
-
-// パーティ情報要求
-int mapif_parse_PartyInfo(int fd, int party_id) {
- struct party *p;
-
- p = numdb_search(party_db, party_id);
- if (p != NULL)
- mapif_party_info(fd, p);
- else
- mapif_party_noinfo(fd, party_id);
-
- return 0;
-}
-
-// パーティ追加要求
-int mapif_parse_PartyAddMember(int fd, int party_id, int account_id, char *nick, char *map, int lv) {
- struct party *p;
- int i;
-
- p = numdb_search(party_db, party_id);
- if (p == NULL) {
- mapif_party_memberadded(fd, party_id, account_id, 1);
- return 0;
- }
-
- for(i = 0; i < MAX_PARTY; i++) {
- if (p->member[i].account_id == 0) {
- int flag = 0;
-
- p->member[i].account_id = account_id;
- memcpy(p->member[i].name, nick, 24);
- memcpy(p->member[i].map, map, 16);
- p->member[i].leader = 0;
- p->member[i].online = 1;
- p->member[i].lv = lv;
- mapif_party_memberadded(fd, party_id, account_id, 0);
- mapif_party_info(-1, p);
-
- if (p->exp > 0 && !party_check_exp_share(p)) {
- p->exp = 0;
- flag = 0x01;
- }
- if (flag)
- mapif_party_optionchanged(fd, p, 0, 0);
- return 0;
- }
- }
- mapif_party_memberadded(fd, party_id, account_id, 1);
-
- return 0;
-}
-
-// パーティー設定変更要求
-int mapif_parse_PartyChangeOption(int fd, int party_id, int account_id, int exp, int item) {
- struct party *p;
- int flag = 0;
-
- p = numdb_search(party_db, party_id);
- if (p == NULL)
- return 0;
-
- p->exp = exp;
- if (exp>0 && !party_check_exp_share(p)) {
- flag |= 0x01;
- p->exp = 0;
- }
-
- p->item = item;
-
- mapif_party_optionchanged(fd, p, account_id, flag);
- return 0;
-}
-
-// パーティ脱退要求
-int mapif_parse_PartyLeave(int fd, int party_id, int account_id) {
- struct party *p;
- int i;
-
- p = numdb_search(party_db, party_id);
- if (p != NULL) {
- for(i = 0; i < MAX_PARTY; i++) {
- if (p->member[i].account_id == account_id) {
- mapif_party_leaved(party_id, account_id, p->member[i].name);
-
- memset(&p->member[i], 0, sizeof(struct party_member));
- if (party_check_empty(p) == 0)
- mapif_party_info(-1, p);// まだ人がいるのでデータ送信
- return 0;
- }
- }
- }
-
- return 0;
-}
-
-// パーティマップ更新要求
-int mapif_parse_PartyChangeMap(int fd, int party_id, int account_id, char *map, int online, int lv) {
- struct party *p;
- int i;
-
- p = numdb_search(party_db, party_id);
- if (p == NULL)
- return 0;
-
- for(i = 0; i < MAX_PARTY; i++) {
- if (p->member[i].account_id == account_id) {
- int flag = 0;
-
- memcpy(p->member[i].map, map, 16);
- p->member[i].online = online;
- p->member[i].lv = lv;
- mapif_party_membermoved(p, i);
-
- if (p->exp > 0 && !party_check_exp_share(p)) {
- p->exp = 0;
- flag = 1;
- }
- if (flag)
- mapif_party_optionchanged(fd, p, 0, 0);
- break;
- }
- }
-
- return 0;
-}
-
-// パーティ解散要求
-int mapif_parse_BreakParty(int fd, int party_id) {
- struct party *p;
-
- p = numdb_search(party_db, party_id);
- if (p == NULL)
- return 0;
-
- numdb_erase(party_db, party_id);
- mapif_party_broken(fd, party_id);
-
- return 0;
-}
-
-// パーティメッセージ送信
-int mapif_parse_PartyMessage(int fd, int party_id, int account_id, char *mes, int len) {
- return mapif_party_message(party_id, account_id, mes, len);
-}
-// パーティチェック要求
-int mapif_parse_PartyCheck(int fd, int party_id, int account_id, char *nick) {
- return party_check_conflict(party_id, account_id, nick);
-}
-
-// map server からの通信
-// ・1パケットのみ解析すること
-// ・パケット長データはinter.cにセットしておくこと
-// ・パケット長チェックや、RFIFOSKIPは呼び出し元で行われるので行ってはならない
-// ・エラーなら0(false)、そうでないなら1(true)をかえさなければならない
-int inter_party_parse_frommap(int fd) {
- switch(RFIFOW(fd,0)) {
- case 0x3020: mapif_parse_CreateParty(fd, RFIFOL(fd,2), RFIFOP(fd,6), RFIFOP(fd,30), RFIFOP(fd,54), RFIFOW(fd,70)); break;
- case 0x3021: mapif_parse_PartyInfo(fd, RFIFOL(fd,2)); break;
- case 0x3022: mapif_parse_PartyAddMember(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOP(fd,10), RFIFOP(fd,34), RFIFOW(fd,50)); break;
- case 0x3023: mapif_parse_PartyChangeOption(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOW(fd,10), RFIFOW(fd,12)); break;
- case 0x3024: mapif_parse_PartyLeave(fd, RFIFOL(fd,2), RFIFOL(fd,6)); break;
- case 0x3025: mapif_parse_PartyChangeMap(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOP(fd,10), RFIFOB(fd,26), RFIFOW(fd,27)); break;
- case 0x3026: mapif_parse_BreakParty(fd, RFIFOL(fd,2)); break;
- case 0x3027: mapif_parse_PartyMessage(fd, RFIFOL(fd,4), RFIFOL(fd,8), RFIFOP(fd,12), RFIFOW(fd,2)-12); break;
- case 0x3028: mapif_parse_PartyCheck(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOP(fd,10)); break;
- default:
- return 0;
- }
-
- return 1;
-}
-
-// サーバーから脱退要求(キャラ削除用)
-int inter_party_leave(int party_id, int account_id) {
- return mapif_parse_PartyLeave(-1, party_id, account_id);
-}
-
+// $Id: int_party.c,v 1.1.1.1 2004/09/10 17:26:51 MagicalTux Exp $ +#include "inter.h" +#include "int_party.h" +#include "mmo.h" +#include "char.h" +#include "socket.h" +#include "db.h" +#include "lock.h" +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +char party_txt[1024] = "save/party.txt"; + +static struct dbt *party_db; +static int party_newid = 100; + +int mapif_party_broken(int party_id, int flag); +int party_check_empty(struct party *p); +int mapif_parse_PartyLeave(int fd, int party_id, int account_id); + +// パーティデータの文字列への変換 +int inter_party_tostr(char *str, struct party *p) { + int i, len; + + len = sprintf(str, "%d\t%s\t%d,%d\t", p->party_id, p->name, p->exp, p->item); + for(i = 0; i < MAX_PARTY; i++) { + struct party_member *m = &p->member[i]; + len += sprintf(str + len, "%d,%d\t%s\t", m->account_id, m->leader, ((m->account_id > 0) ? m->name : "NoMember")); + } + + return 0; +} + +// パーティデータの文字列からの変換 +int inter_party_fromstr(char *str, struct party *p) { + int i, j; + int tmp_int[16]; + char tmp_str[256]; + + memset(p, 0, sizeof(struct party)); + +// printf("sscanf party main info\n"); + if (sscanf(str, "%d\t%[^\t]\t%d,%d\t", &tmp_int[0], tmp_str, &tmp_int[1], &tmp_int[2]) != 4) + return 1; + + p->party_id = tmp_int[0]; + strcpy(p->name, tmp_str); + p->exp = tmp_int[1]; + p->item = tmp_int[2]; +// printf("%d [%s] %d %d\n", tmp_int[0], tmp_str[0], tmp_int[1], tmp_int[2]); + + for(j = 0; j < 3 && str != NULL; j++) + str = strchr(str + 1, '\t'); + + for(i = 0; i < MAX_PARTY; i++) { + struct party_member *m = &p->member[i]; + if (str == NULL) + return 1; +// printf("sscanf party member info %d\n", i); + + if (sscanf(str + 1, "%d,%d\t%[^\t]\t", &tmp_int[0], &tmp_int[1], tmp_str) != 3) + return 1; + + m->account_id = tmp_int[0]; + m->leader = tmp_int[1]; + strncpy(m->name, tmp_str, sizeof(m->name)); +// printf(" %d %d [%s]\n", tmp_int[0], tmp_int[1], tmp_str); + + for(j = 0; j < 2 && str != NULL; j++) + str = strchr(str + 1, '\t'); + } + + return 0; +} + +// パーティデータのロード +int inter_party_init() { + char line[8192]; + struct party *p; + FILE *fp; + int c = 0; + int i, j; + + party_db = numdb_init(); + + if ((fp = fopen(party_txt, "r")) == NULL) + return 1; + + while(fgets(line, sizeof(line) - 1, fp)) { + j = 0; + if (sscanf(line, "%d\t%%newid%%\n%n", &i, &j) == 1 && j > 0 && party_newid <= i) { + party_newid = i; + continue; + } + + p = calloc(sizeof(struct party), 1); + if (p == NULL){ + printf("int_party: out of memory!\n"); + exit(0); + } + memset(p, 0, sizeof(struct party)); + if (inter_party_fromstr(line, p) == 0 && p->party_id > 0) { + if (p->party_id >= party_newid) + party_newid = p->party_id + 1; + numdb_insert(party_db, p->party_id, p); + party_check_empty(p); + } else { + printf("int_party: broken data [%s] line %d\n", party_txt, c + 1); + free(p); + } + c++; + } + fclose(fp); +// printf("int_party: %s read done (%d parties)\n", party_txt, c); + + return 0; +} + +// パーティーデータのセーブ用 +int inter_party_save_sub(void *key, void *data, va_list ap) { + char line[8192]; + FILE *fp; + + inter_party_tostr(line, (struct party *)data); + fp = va_arg(ap, FILE *); + fprintf(fp, "%s" RETCODE, line); + + return 0; +} + +// パーティーデータのセーブ +int inter_party_save() { + FILE *fp; + int lock; + + if ((fp = lock_fopen(party_txt, &lock)) == NULL) { + printf("int_party: cant write [%s] !!! data is lost !!!\n", party_txt); + return 1; + } + numdb_foreach(party_db, inter_party_save_sub, fp); +// fprintf(fp, "%d\t%%newid%%\n", party_newid); + lock_fclose(fp,party_txt, &lock); +// printf("int_party: %s saved.\n", party_txt); + + return 0; +} + +// パーティ名検索用 +int search_partyname_sub(void *key,void *data,va_list ap) { + struct party *p = (struct party *)data,**dst; + char *str; + + str = va_arg(ap, char *); + dst = va_arg(ap, struct party **); + if (strcmpi(p->name, str) == 0) + *dst = p; + + return 0; +} + +// パーティ名検索 +struct party* search_partyname(char *str) { + struct party *p = NULL; + numdb_foreach(party_db, search_partyname_sub, str, &p); + + return p; +} + +// EXP公平分配できるかチェック +int party_check_exp_share(struct party *p) { + int i; + int maxlv = 0, minlv = 0x7fffffff; + + for(i = 0; i < MAX_PARTY; i++) { + int lv = p->member[i].lv; + if (p->member[i].online) { + if (lv < minlv) + minlv = lv; + if (maxlv < lv) + maxlv = lv; + } + } + + return (maxlv == 0 || maxlv-minlv <= party_share_level); +} + +// パーティが空かどうかチェック +int party_check_empty(struct party *p) { + int i; + +// printf("party check empty %08X\n", (int)p); + for(i = 0; i < MAX_PARTY; i++) { +// printf("%d acc=%d\n", i, p->member[i].account_id); + if (p->member[i].account_id > 0) { + return 0; + } + } + // 誰もいないので解散 + mapif_party_broken(p->party_id, 0); + numdb_erase(party_db, p->party_id); + free(p); + + return 1; +} + +// キャラの競合がないかチェック用 +int party_check_conflict_sub(void *key, void *data, va_list ap) { + struct party *p = (struct party *)data; + int party_id, account_id, i; + char *nick; + + party_id=va_arg(ap, int); + account_id=va_arg(ap, int); + nick=va_arg(ap, char *); + + if (p->party_id == party_id) // 本来の所属なので問題なし + return 0; + + for(i = 0; i < MAX_PARTY; i++) { + if (p->member[i].account_id == account_id && strcmp(p->member[i].name, nick) == 0) { + // 別のパーティに偽の所属データがあるので脱退 + printf("int_party: party conflict! %d %d %d\n", account_id, party_id, p->party_id); + mapif_parse_PartyLeave(-1, p->party_id, account_id); + } + } + + return 0; +} + +// キャラの競合がないかチェック +int party_check_conflict(int party_id, int account_id, char *nick) { + numdb_foreach(party_db, party_check_conflict_sub, party_id, account_id, nick); + + return 0; +} + +//------------------------------------------------------------------- +// map serverへの通信 + +// パーティ作成可否 +int mapif_party_created(int fd,int account_id, struct party *p) { + WFIFOW(fd,0) = 0x3820; + WFIFOL(fd,2) = account_id; + if (p != NULL) { + WFIFOB(fd,6) = 0; + WFIFOL(fd,7) = p->party_id; + memcpy(WFIFOP(fd,11), p->name, 24); + printf("int_party: created! %d %s\n", p->party_id, p->name); + } else { + WFIFOB(fd,6) = 1; + WFIFOL(fd,7) = 0; + memcpy(WFIFOP(fd,11), "error", 24); + } + WFIFOSET(fd,35); + + return 0; +} + +// パーティ情報見つからず +int mapif_party_noinfo(int fd, int party_id) { + WFIFOW(fd,0) = 0x3821; + WFIFOW(fd,2) = 8; + WFIFOL(fd,4) = party_id; + WFIFOSET(fd,8); + printf("int_party: info not found %d\n", party_id); + + return 0; +} + +// パーティ情報まとめ送り +int mapif_party_info(int fd, struct party *p) { + unsigned char buf[4 + sizeof(struct party)]; + + WBUFW(buf,0) = 0x3821; + memcpy(buf + 4, p, sizeof(struct party)); + WBUFW(buf,2) = 4 + sizeof(struct party); + if (fd < 0) + mapif_sendall(buf, WBUFW(buf,2)); + else + mapif_send(fd, buf, WBUFW(buf,2)); +// printf("int_party: info %d %s\n", p->party_id, p->name); + + return 0; +} + +// パーティメンバ追加可否 +int mapif_party_memberadded(int fd, int party_id, int account_id, int flag) { + WFIFOW(fd,0) = 0x3822; + WFIFOL(fd,2) = party_id; + WFIFOL(fd,6) = account_id; + WFIFOB(fd,10) = flag; + WFIFOSET(fd,11); + + return 0; +} + +// パーティ設定変更通知 +int mapif_party_optionchanged(int fd,struct party *p, int account_id, int flag) { + unsigned char buf[15]; + + WBUFW(buf,0) = 0x3823; + WBUFL(buf,2) = p->party_id; + WBUFL(buf,6) = account_id; + WBUFW(buf,10) = p->exp; + WBUFW(buf,12) = p->item; + WBUFB(buf,14) = flag; + if (flag == 0) + mapif_sendall(buf, 15); + else + mapif_send(fd, buf, 15); + printf("int_party: option changed %d %d %d %d %d\n", p->party_id, account_id, p->exp, p->item, flag); + + return 0; +} + +// パーティ脱退通知 +int mapif_party_leaved(int party_id,int account_id, char *name) { + unsigned char buf[34]; + + WBUFW(buf,0) = 0x3824; + WBUFL(buf,2) = party_id; + WBUFL(buf,6) = account_id; + memcpy(WBUFP(buf,10), name, 24); + mapif_sendall(buf, 34); + printf("int_party: party leaved %d %d %s\n", party_id, account_id, name); + + return 0; +} + +// パーティマップ更新通知 +int mapif_party_membermoved(struct party *p, int idx) { + unsigned char buf[29]; + + WBUFW(buf,0) = 0x3825; + WBUFL(buf,2) = p->party_id; + WBUFL(buf,6) = p->member[idx].account_id; + memcpy(WBUFP(buf,10), p->member[idx].map, 16); + WBUFB(buf,26) = p->member[idx].online; + WBUFW(buf,27) = p->member[idx].lv; + mapif_sendall(buf, 29); + + return 0; +} + +// パーティ解散通知 +int mapif_party_broken(int party_id, int flag) { + unsigned char buf[7]; + WBUFW(buf,0) = 0x3826; + WBUFL(buf,2) = party_id; + WBUFB(buf,6) = flag; + mapif_sendall(buf, 7); + printf("int_party: broken %d\n", party_id); + + return 0; +} + +// パーティ内発言 +int mapif_party_message(int party_id, int account_id, char *mes, int len) { + unsigned char buf[len+12]; + + WBUFW(buf,0) = 0x3827; + WBUFW(buf,2) = len + 12; + WBUFL(buf,4) = party_id; + WBUFL(buf,8) = account_id; + memcpy(WBUFP(buf,12), mes, len); + mapif_sendall(buf,len + 12); + + return 0; +} + +//------------------------------------------------------------------- +// map serverからの通信 + + +// パーティ +int mapif_parse_CreateParty(int fd, int account_id, char *name, char *nick, char *map, int lv) { + struct party *p; + int i; + + for(i = 0; i < 24 && name[i]; i++) { + if (!(name[i] & 0xe0) || name[i] == 0x7f) { + printf("int_party: illegal party name [%s]\n", name); + mapif_party_created(fd, account_id, NULL); + return 0; + } + } + + if ((p = search_partyname(name)) != NULL) { + printf("int_party: same name party exists [%s]\n", name); + mapif_party_created(fd, account_id, NULL); + return 0; + } + p = calloc(sizeof(struct party), 1); + if (p == NULL) { + printf("int_party: out of memory !\n"); + mapif_party_created(fd,account_id,NULL); + return 0; + } + memset(p, 0, sizeof(struct party)); + p->party_id = party_newid++; + memcpy(p->name, name, 24); + p->exp = 0; + p->item = 0; + p->member[0].account_id = account_id; + memcpy(p->member[0].name, nick, 24); + memcpy(p->member[0].map, map, 16); + p->member[0].leader = 1; + p->member[0].online = 1; + p->member[0].lv = lv; + + numdb_insert(party_db, p->party_id, p); + + mapif_party_created(fd, account_id, p); + mapif_party_info(fd, p); + + return 0; +} + +// パーティ情報要求 +int mapif_parse_PartyInfo(int fd, int party_id) { + struct party *p; + + p = numdb_search(party_db, party_id); + if (p != NULL) + mapif_party_info(fd, p); + else + mapif_party_noinfo(fd, party_id); + + return 0; +} + +// パーティ追加要求 +int mapif_parse_PartyAddMember(int fd, int party_id, int account_id, char *nick, char *map, int lv) { + struct party *p; + int i; + + p = numdb_search(party_db, party_id); + if (p == NULL) { + mapif_party_memberadded(fd, party_id, account_id, 1); + return 0; + } + + for(i = 0; i < MAX_PARTY; i++) { + if (p->member[i].account_id == 0) { + int flag = 0; + + p->member[i].account_id = account_id; + memcpy(p->member[i].name, nick, 24); + memcpy(p->member[i].map, map, 16); + p->member[i].leader = 0; + p->member[i].online = 1; + p->member[i].lv = lv; + mapif_party_memberadded(fd, party_id, account_id, 0); + mapif_party_info(-1, p); + + if (p->exp > 0 && !party_check_exp_share(p)) { + p->exp = 0; + flag = 0x01; + } + if (flag) + mapif_party_optionchanged(fd, p, 0, 0); + return 0; + } + } + mapif_party_memberadded(fd, party_id, account_id, 1); + + return 0; +} + +// パーティー設定変更要求 +int mapif_parse_PartyChangeOption(int fd, int party_id, int account_id, int exp, int item) { + struct party *p; + int flag = 0; + + p = numdb_search(party_db, party_id); + if (p == NULL) + return 0; + + p->exp = exp; + if (exp>0 && !party_check_exp_share(p)) { + flag |= 0x01; + p->exp = 0; + } + + p->item = item; + + mapif_party_optionchanged(fd, p, account_id, flag); + return 0; +} + +// パーティ脱退要求 +int mapif_parse_PartyLeave(int fd, int party_id, int account_id) { + struct party *p; + int i; + + p = numdb_search(party_db, party_id); + if (p != NULL) { + for(i = 0; i < MAX_PARTY; i++) { + if (p->member[i].account_id == account_id) { + mapif_party_leaved(party_id, account_id, p->member[i].name); + + memset(&p->member[i], 0, sizeof(struct party_member)); + if (party_check_empty(p) == 0) + mapif_party_info(-1, p);// まだ人がいるのでデータ送信 + return 0; + } + } + } + + return 0; +} + +// パーティマップ更新要求 +int mapif_parse_PartyChangeMap(int fd, int party_id, int account_id, char *map, int online, int lv) { + struct party *p; + int i; + + p = numdb_search(party_db, party_id); + if (p == NULL) + return 0; + + for(i = 0; i < MAX_PARTY; i++) { + if (p->member[i].account_id == account_id) { + int flag = 0; + + memcpy(p->member[i].map, map, 16); + p->member[i].online = online; + p->member[i].lv = lv; + mapif_party_membermoved(p, i); + + if (p->exp > 0 && !party_check_exp_share(p)) { + p->exp = 0; + flag = 1; + } + if (flag) + mapif_party_optionchanged(fd, p, 0, 0); + break; + } + } + + return 0; +} + +// パーティ解散要求 +int mapif_parse_BreakParty(int fd, int party_id) { + struct party *p; + + p = numdb_search(party_db, party_id); + if (p == NULL) + return 0; + + numdb_erase(party_db, party_id); + mapif_party_broken(fd, party_id); + + return 0; +} + +// パーティメッセージ送信 +int mapif_parse_PartyMessage(int fd, int party_id, int account_id, char *mes, int len) { + return mapif_party_message(party_id, account_id, mes, len); +} +// パーティチェック要求 +int mapif_parse_PartyCheck(int fd, int party_id, int account_id, char *nick) { + return party_check_conflict(party_id, account_id, nick); +} + +// map server からの通信 +// ・1パケットのみ解析すること +// ・パケット長データはinter.cにセットしておくこと +// ・パケット長チェックや、RFIFOSKIPは呼び出し元で行われるので行ってはならない +// ・エラーなら0(false)、そうでないなら1(true)をかえさなければならない +int inter_party_parse_frommap(int fd) { + switch(RFIFOW(fd,0)) { + case 0x3020: mapif_parse_CreateParty(fd, RFIFOL(fd,2), RFIFOP(fd,6), RFIFOP(fd,30), RFIFOP(fd,54), RFIFOW(fd,70)); break; + case 0x3021: mapif_parse_PartyInfo(fd, RFIFOL(fd,2)); break; + case 0x3022: mapif_parse_PartyAddMember(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOP(fd,10), RFIFOP(fd,34), RFIFOW(fd,50)); break; + case 0x3023: mapif_parse_PartyChangeOption(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOW(fd,10), RFIFOW(fd,12)); break; + case 0x3024: mapif_parse_PartyLeave(fd, RFIFOL(fd,2), RFIFOL(fd,6)); break; + case 0x3025: mapif_parse_PartyChangeMap(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOP(fd,10), RFIFOB(fd,26), RFIFOW(fd,27)); break; + case 0x3026: mapif_parse_BreakParty(fd, RFIFOL(fd,2)); break; + case 0x3027: mapif_parse_PartyMessage(fd, RFIFOL(fd,4), RFIFOL(fd,8), RFIFOP(fd,12), RFIFOW(fd,2)-12); break; + case 0x3028: mapif_parse_PartyCheck(fd, RFIFOL(fd,2), RFIFOL(fd,6), RFIFOP(fd,10)); break; + default: + return 0; + } + + return 1; +} + +// サーバーから脱退要求(キャラ削除用) +int inter_party_leave(int party_id, int account_id) { + return mapif_parse_PartyLeave(-1, party_id, account_id); +} + |