소스 검색

git-svn-id: https://svn.code.sf.net/p/rathena/svn/athena@290 54d463be-8e91-2dee-dedb-b68131a5f0ec

mc_cameri 20 년 전
부모
커밋
fcfbef1124
2개의 변경된 파일296개의 추가작업 그리고 0개의 파일을 삭제
  1. 254 0
      src/map/charcommand.c
  2. 42 0
      src/map/charcommand.h

+ 254 - 0
src/map/charcommand.c

@@ -0,0 +1,254 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+
+#include "../common/socket.h"
+#include "../common/timer.h"
+#include "../common/nullpo.h"
+
+#include "log.h"
+#include "clif.h"
+#include "chrif.h"
+#include "intif.h"
+#include "itemdb.h"
+#include "map.h"
+#include "pc.h"
+#include "skill.h"
+#include "mob.h"
+#include "pet.h"
+#include "battle.h"
+#include "party.h"
+#include "guild.h"
+#include "charcommand.h"
+#include "atcommand.h"
+#include "script.h"
+#include "npc.h"
+#include "trade.h"
+#include "core.h"
+
+static char command_symbol = '#';
+
+static char msg_table[1000][1024]; // Server messages (0-499 reserved for GM commands, 500-999 reserved for others)
+
+#define CHARCOMMAND_FUNC(x) int charcommand_ ## x (const int fd, struct map_session_data* sd, const char* command, const char* message)
+#ifdef TXT_ONLY
+/* TXT_ONLY */
+	CHARCOMMAND_FUNC(test);
+/* TXT_ONLY */
+#else
+/* SQL-only */
+	//CHARCOMMAND_FUNC(funcname);
+/* SQL Only */
+#endif
+
+/*==========================================
+ *CharCommandInfo charcommand_info[]構造体の定義
+ *------------------------------------------
+ */
+
+// First char of commands is configured in charcommand_athena.conf. Leave @ in this list for default value.
+// to set default level, read charcommand_athena.conf first please.
+static CharCommandInfo charcommand_info[] = {
+	
+#ifdef TXT_ONLY
+/* TXT_ONLY */
+//	{ CharCommandType,				"#name",			level, charcommand_func },
+	{ CharCommandTest,				"#test",			0,	charcommand_test },
+/* TXT_ONLY */
+#else
+/* SQL-only */
+//	{ CharCommandType,				"#name",			level, charcommand_func },
+/* SQL Only */
+#endif
+
+// add new commands before this line
+	{ CharCommand_Unknown,             NULL,                1, NULL }
+};
+
+
+int get_charcommand_level(const CharCommandType type) {
+	int i;
+
+	for (i = 0; charcommand_info[i].type != CharCommand_None; i++)
+		if (charcommand_info[i].type == type)
+			return charcommand_info[i].level;
+
+	return 100; // 100: command can not be used
+}
+
+/*==========================================
+ *is_charcommand @コマンドに存在するかどうか確認する
+ *------------------------------------------
+ */
+CharCommandType
+is_charcommand(const int fd, struct map_session_data* sd, const char* message, int gmlvl) {
+	const char* str = message;
+	int s_flag = 0;
+	CharCommandInfo info;
+	CharCommandType type;
+
+	nullpo_retr(CharCommand_None, sd);
+
+	if (!message || !*message)
+		return CharCommand_None;
+
+	memset(&info, 0, sizeof(info));
+	str += strlen(sd->status.name);
+	while (*str && (isspace(*str) || (s_flag == 0 && *str == ':'))) {
+		if (*str == ':')
+			s_flag = 1;
+		str++;
+	}
+	if (!*str)
+		return CharCommand_None;
+
+	type = charcommand(gmlvl > 0 ? gmlvl : pc_isGM(sd), str, &info);
+	if (type != CharCommand_None) {
+		char command[100];
+		char output[200];
+		const char* p = str;
+		memset(command, '\0', sizeof(command));
+		memset(output, '\0', sizeof(output));
+		while (*p && !isspace(*p))
+			p++;
+		if (p - str >= sizeof(command)) // too long
+			return CharCommand_Unknown;
+		strncpy(command, str, p - str);
+		while (isspace(*p))
+			p++;
+
+		if (type == CharCommand_Unknown || info.proc == NULL) {
+			sprintf(output, msg_table[153], command); // %s is Unknown Command.
+			clif_displaymessage(fd, output);
+		} else {
+			if (info.proc(fd, sd, command, p) != 0) {
+				// Command can not be executed
+				sprintf(output, msg_table[154], command); // %s failed.
+				clif_displaymessage(fd, output);
+			}
+		}
+
+		return info.type;
+	}
+
+	return CharCommand_None;
+}
+
+/*==========================================
+ *
+ *------------------------------------------
+ */
+CharCommandType charcommand(const int level, const char* message, struct CharCommandInfo* info) {
+	char* p = (char *)message; 
+
+	if (!info)
+		return CharCommand_None;
+	if (battle_config.atc_gmonly != 0 && !level) // level = pc_isGM(sd)
+		return CharCommand_None;
+	if (!p || !*p) {
+		fprintf(stderr, "char command message is empty\n");
+		return CharCommand_None;
+	}
+
+	if (*p == command_symbol) { // check first char.
+		char command[101];
+		int i = 0;
+		memset(info, 0, sizeof(CharCommandInfo));
+		sscanf(p, "%100s", command);
+		command[sizeof(command)-1] = '\0';
+
+		while (charcommand_info[i].type != CharCommand_Unknown) {
+			if (strcmpi(command+1, charcommand_info[i].command+1) == 0 && level >= charcommand_info[i].level) {
+				p[0] = charcommand_info[i].command[0]; // set correct first symbol for after.
+				break;
+			}
+			i++;
+		}
+
+		if (charcommand_info[i].type == CharCommand_Unknown) {
+			// doesn't return Unknown if player is normal player (display the text, not display: unknown command)
+			if (level == 0)
+				return CharCommand_None;
+			else
+				return CharCommand_Unknown;
+		}
+		memcpy(info, &charcommand_info[i], sizeof charcommand_info[i]);
+	} else {
+		return CharCommand_None;
+	}
+
+	return info->type;
+}
+
+
+/*==========================================
+ *
+ *------------------------------------------
+ */
+static CharCommandInfo* get_charcommandinfo_byname(const char* name) {
+	int i;
+
+	for (i = 0; charcommand_info[i].type != CharCommand_Unknown; i++)
+		if (strcmpi(charcommand_info[i].command + 1, name) == 0)
+			return &charcommand_info[i];
+
+	return NULL;
+}
+
+/*==========================================
+ *
+ *------------------------------------------
+ */
+int charcommand_config_read(const char *cfgName) {
+	char line[1024], w1[1024], w2[1024];
+	CharCommandInfo* p;
+	FILE* fp;
+
+	if ((fp = fopen(cfgName, "r")) == NULL) {
+		printf("Char commands configuration file not found: %s\n", cfgName);
+		return 1;
+	}
+
+	while (fgets(line, sizeof(line)-1, fp)) {
+		if (line[0] == '/' && line[1] == '/')
+			continue;
+
+		if (sscanf(line, "%1023[^:]:%1023s", w1, w2) != 2)
+			continue;
+		p = get_charcommandinfo_byname(w1);
+		if (p != NULL) {
+			p->level = atoi(w2);
+			if (p->level > 100)
+				p->level = 100;
+			else if (p->level < 0)
+				p->level = 0;
+		}
+
+		if (strcmpi(w1, "import") == 0)
+			charcommand_config_read(w2);
+		else if (strcmpi(w1, "command_symbol") == 0 && w2[0] > 31 &&
+		         w2[0] != '/' && // symbol of standard ragnarok GM commands
+		         w2[0] != '%' && // symbol of party chat speaking
+				 w2[0] != '@')	 // symbol for @commands
+			command_symbol = w2[0];
+	}
+	fclose(fp);
+
+	return 0;
+}
+
+
+
+/*==========================================
+// # command processing functions
+ *------------------------------------------
+ */
+int 
+charcommand_test (const int fd, struct map_session_data* sd, 
+	const char* command, const char* message) {
+	clif_displaymessage(fd,"Works!");
+	return 0;
+}
+

+ 42 - 0
src/map/charcommand.h

@@ -0,0 +1,42 @@
+#ifndef _CHARCOMMAND_H_
+#define _CHARCOMMAND_H_
+
+enum CharCommandType {
+	CharCommand_None = -1,
+
+#ifdef TXT_ONLY
+/* TXT_ONLY */
+	CharCommandTest,
+/* TXT_ONLY */
+#else
+/* SQL-only */
+
+/* SQL Only */
+#endif
+	
+	// End. No more commans after this line.
+	CharCommand_Unknown,
+	CharCommand_MAX
+};
+
+typedef enum CharCommandType CharCommandType;
+
+typedef struct CharCommandInfo {
+	CharCommandType type;
+	const char* command;
+	int level;
+	int (*proc)(const int, struct map_session_data*,
+		const char* command, const char* message);
+} CharCommandInfo;
+
+CharCommandType
+is_charcommand(const int fd, struct map_session_data* sd, const char* message, int gmlvl);
+
+CharCommandType charcommand(
+	const int level, const char* message, CharCommandInfo* info);
+int get_charcommand_level(const CharCommandType type);
+
+int charcommand_config_read(const char *cfgName);
+
+#endif
+