1 /*
2  * mvdsv_mod_frags.c
3  * main mod_frags file
4  * cases all functions in "stdout" form
5  * to use it at console
6  * and main function with example of using
7  * (c) kreon 2005
8  * Idea by gLAd
9  *
10  */
11 /*
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License
14 as published by the Free Software Foundation; either version 2
15 of the License, or (at your option) any later version.
16 
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20 
21 See the GNU General Public License for more details.
22 
23 You should have received a copy of the GNU General Public License
24 along with this program; if not, write to the Free Software
25 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
26 
27 
28 */
29 
30 #ifndef CLIENTONLY
31 #include "qwsvdef.h"
32 #ifndef SERVERONLY
33 #include "pcre.h"
34 #endif
35 #include "sv_mod_frags.h"
36 
37 qwmsg_t *qwmsg[MOD_MSG_MAX + 1];
38 static qbool qwm_static = true;
39 
free_qwmsg_t(qwmsg_t ** qwmsg1)40 void free_qwmsg_t(qwmsg_t **qwmsg1)
41 {
42 	int i;
43 
44 	if (!qwm_static) {
45 		for (i = 0; qwmsg1[i]; i++) {
46 			Q_free(qwmsg1[i]->str);
47 			Q_free(qwmsg1[i]);
48 		}
49 	}
50 }
51 
sv_mod_msg_file_OnChange(cvar_t * cvar,char * value,qbool * cancel)52 void sv_mod_msg_file_OnChange(cvar_t *cvar, char *value, qbool *cancel)
53 {
54 	FILE *fp = NULL;
55 	char *str_tok, buf[128];
56 	size_t len;
57 	int i;
58 
59 	free_qwmsg_t(qwmsg);
60 
61 	if (value[0])
62 		fp = fopen(value, "r");
63 
64 	if (fp == NULL)
65 	{
66 		if (value[0])
67 			Con_Printf("WARNING: sv_mod_msg_file_OnChange: can't open file %s.\n", value);
68 
69 		for (i = 0; i < MOD_MSG_MAX && qwmsg_def[i].str; i++) {
70 			qwmsg[i] = &qwmsg_def[i];
71 		}
72 		qwm_static = true;
73 		Con_DPrintf("Initialized default mod messages.\nTotal: %d messages.\n", i);
74 	}
75 	else
76 	{
77 		for (i = 0; i < MOD_MSG_MAX && !feof(fp); i++)
78 		{
79 			if (fgets(buf, sizeof(buf), fp))
80 			{
81 				qwmsg[i] = (qwmsg_t *) Q_malloc (sizeof(qwmsg_t));
82 				// fill system_id
83 				str_tok = (char *)strtok(buf, "#");
84 				qwmsg[i]->msg_type = Q_atoi(str_tok);
85 				// fill weapon_id
86 				str_tok = (char *)strtok(NULL, "#");
87 				qwmsg[i]->id = Q_atoi(str_tok);
88 				// fill pl_count
89 				str_tok = (char *)strtok(NULL, "#");
90 				qwmsg[i]->pl_count = Q_atoi(str_tok) == 1 ? 1 : 2;
91 				// fill reverse
92 				str_tok = (char *)strtok(NULL, "#");
93 				qwmsg[i]->reverse = Q_atoi(str_tok) ? true : false;
94 				// fill str
95 				str_tok = (char *)strtok(NULL, "#");
96 
97 				len = strlen (str_tok) + 1;
98 				qwmsg[i]->str =  (char *) Q_malloc (len);
99 				strlcpy(qwmsg[i]->str, str_tok, len);
100 			}
101 			else
102 				break;
103 			//            Sys_Printf("msg_type = %d, id = %d, pl_count = %d, str = %s, reverse = %d\n",
104 			//	qwmsg[i]->msg_type, qwmsg[i]->id, qwmsg[i]->pl_count, qwmsg[i]->str, qwmsg[i]->reverse);
105 		}
106 		qwm_static = false;
107 		Con_DPrintf("Initialized mod messages from file %s.\nTotal: %d messages.\n", value, i);
108 		fclose(fp);
109 	}
110 	qwmsg[i] = NULL;
111 	*cancel = false;
112 }
113 
qwmsg_pcre_check(const char * str,const char * qwm_str,int str_len)114 const char **qwmsg_pcre_check(const char *str, const char *qwm_str, int str_len)
115 {
116 	pcre *reg;
117 	int *ovector[32];
118 	const char *errbuf;
119 	int erroffset = 0;
120 	const char **buf = NULL;
121 	int stringcount;
122 
123 	if (!(reg = pcre_compile(qwm_str, 0, &errbuf, &erroffset, 0)))
124 	{
125 		Sys_Printf("WARNING: qwmsg_pcre_check: pcre_compile(%s) error %s\n", qwm_str, errbuf);
126 		return NULL;
127 	}
128 
129 	stringcount = pcre_exec(reg, NULL, str, str_len, 0, 0, (int *)&ovector[0], 32);
130 	pcre_free(reg);
131 	if (stringcount <= 0) {
132 		return NULL;
133 	}
134 
135 	pcre_get_substring_list(str, (int *)&ovector[0], stringcount, &buf);
136 	return buf;
137 }
138 
139 // main function
parse_mod_string(char * str)140 char *parse_mod_string(char *str)
141 {
142 	const char **buf;
143 	int i, str_len = strlen(str);
144 	char *ret = NULL;
145 	for (i = 0; qwmsg[i]; i++)
146 	{
147 		if ((buf = qwmsg_pcre_check(str, qwmsg[i]->str, str_len)))
148 		{
149 			int pl1, pl2;
150 			switch (qwmsg[i]->msg_type)
151 			{
152 			case WEAPON:
153 				pl1 = pl2 = 1;
154 				switch (qwmsg[i]->pl_count)
155 				{
156 				case 2:
157 					pl2 += qwmsg[i]->reverse;
158 					pl1 = 3 - pl2;
159 				case 1:
160 					str_len = strlen(buf[pl1]) + strlen(buf[pl2]) + strlen(qw_weapon[qwmsg[i]->id]) + 5 + 10;
161 					ret = (char *) Q_malloc (str_len);
162 					snprintf(ret, str_len, "%s\\%s\\%s\\%d\n", buf[pl1], buf[pl2], qw_weapon[qwmsg[i]->id], (int)time(NULL));
163 					break;
164 				default: ret = NULL;
165 				}
166 				break;
167 			case SYSTEM:
168 				str_len = strlen(buf[1]) * 2 + strlen(qw_system[qwmsg[i]->id]) + 4 + 10;
169 				ret = (char *) Q_malloc (str_len);
170 				snprintf(ret, str_len, "%s\\%s\\%d\n", buf[1], qw_system[qwmsg[i]->id], (int)time(NULL));
171 				break;
172 			default: ret = NULL;
173 			}
174 			pcre_free_substring_list(buf);
175 			break;
176 		}
177 	}
178 	return ret;
179 }
180 
181 #endif // !CLIENTONLY
182