搜索
查看: 68590|回复: 375

[技术类][原创]Psychostats2.3.3安装之十全大补贴

[复制链接]
发表于 2006-6-25 13:21:56 | 显示全部楼层 |阅读模式 来自 天津
与Songsong在dt-club发表第一篇关于Psychostats的安装使用说明时隔近两年,Psychostats正式发布的版本已经到了2.3.3(3.0已经出Demo了,估计正式版也会很快发布了)。我是2005年才发现这个系统,觉得做得非常棒。于是自己动手开始安装,仔细研读了点通所有关于Psychostats的帖子,但是安装过程还是磕磕绊绊不是很顺利,多方寻求帮助无果的情况下只好在Psychostats的官方论坛上发贴,希望能从Jason Morriss(也就是tormtrooper)和JTP10181那里获得帮助,最后终于功夫不负有心人,遇到的问题都一一解决了。今天把解决方法发出来分享给大家,希望能对于我有同样爱好的朋友有所帮助。


前注:
[1]在阅读本文之前请仔细阅读Songsong发的“Psychostats2.2.b调试、安装、使用帮助”
[2]本文讨论的环境为Win2003+CS1.5 Build2615(Ver4.1.1.1e)+AMXX1.6+MM1.19p28<+……>
[3]在严格安装Songsong发的说明安装的情况下出现以下问题(可能是系统Bug,或是被Songsong忽略所致)
[4]安装时注意:在运行Install.pl前应先运行update.pl将安装文件升级到最新版本。安装后依次运行install.pl -resetdb -profiles和install.pl -step web -useconf以解决缺少plr_profile表和页面错误的的问题.
在安装Psychostats2.3.3后出现如下问题:
Q1:“玩家”等几个页面打开后是空白页或者是乱码
Q2:服务器页面出现“服务器无法响应”的提示
Q3:PIP插件安装后在Console里输入ps_password <password>报错:
[PsychoStats] SQL error. Contact your admin: 'Unknown column 'password' in 'field list''

Fix1
打开<stats root>\include\common.php
找到(第165行):
header('Content-Type: text/html; charset=utf-8');
修改为:
header('Content-Type: text/html; charset=gb2312');

PS:这是一个系统的Bug。Psychstats的编码格式为UTF-8,在用户打开Psychstats的相应页面时,系统会根据用户浏览器默认语言的编码自动选择以那种语言编码显示。问题就出在这,实际情况是Psychstats已经确认了浏览器的编码格式但没有进行自动转换,导致只有以默认的english显示正确。该问题存在于包括简体中文在内的多个语言的PS2的多个release。


Fix2
打开<stats root>\server.php
注意有这样一行:
'querytype' => 'halflife', // change this to 'oldhalflife' if you're using CS 1.5 or lower
将halflife改为oldhalflife即可解决。

PS:该问题仅存在于CS1.5中,1.5以上版本在按照“前注[4]”操作后就不会出现。由于CS1.5以上的数据查询方法与1.5不同所以在这里应该选择与相应版本对应的数据查询方式。

Fix3
将以下代码另存为.sma格式,使用相应的AMXX或AMX编译器进行编译后复制到<CS root>\cstrike\addons\amxmodx\plugins下
  1. /* AMX Mod (X)
  2. *   PsychoStats Interface Plugin
  3. *
  4. *   by Jason Morriss <[email]stormtrooper@psychostats.com[/email]>
  5. *   and JTP10181 <[email]jtp@jtpage.net[/email]>
  6. *   [url=http://www.psychostats.com/]http://www.psychostats.com/[/url]
  7. *
  8. *
  9. *  This program is free software; you can redistribute it and/or modify it
  10. *  under the terms of the GNU General Public License as published by the
  11. *  Free Software Foundation; either version 2 of the License, or (at
  12. *  your option) any later version.
  13. *
  14. *  This program is distributed in the hope that it will be useful, but
  15. *  WITHOUT ANY WARRANTY; without even the implied warranty of
  16. *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. *  General Public License for more details.
  18. *
  19. *  You should have received a copy of the GNU General Public License
  20. *  along with this program; if not, write to the Free Software Foundation,
  21. *  Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22. *
  23. *  In addition, as a special exception, the author gives permission to
  24. *  link the code of this program with the Half-Life Game Engine ("HL
  25. *  Engine") and Modified Game Libraries ("MODs") developed by Valve,
  26. *  L.L.C ("Valve"). You must obey the GNU General Public License in all
  27. *  respects for all of the code used other than the HL Engine and MODs
  28. *  from Valve. If you modify this file, you may extend this exception
  29. *  to your version of the file, but you are not obligated to do so. If
  30. *  you do not wish to do so, delete this exception statement from your
  31. *  version.
  32. */
  33. //Do Not TOUCH. This is for debugging only.
  34. //#define DEBUG
  35. //#define MYSQLDEBUG
  36. #if defined DEBUG
  37. new debug_authid[]  = "STEAM_0:0:123456";
  38. new debug_name[] = "Stormtrooper";
  39. new debug_ipaddr[] = "0.0.0.0";
  40. #endif
  41. // *** DO NOT EDIT BELOW HERE ***
  42. #include <amxconst>
  43. #if defined AMXX_VERSION
  44.   #include <amxmodx>
  45.   #include <dbi>
  46. #else
  47.   #include <amxmod>
  48.   #include <mysql>
  49. #endif
  50. #include <amxmisc>
  51. // GLOBAL VARIABLES
  52. new ps_version[] = "1.4";
  53. new pshost[64], psuser[32], pspass[32], psdb[32], plrtbl[32], psuniqueid[16], psurl[255], psrankurl[255], psadminpw[64];
  54. new plriplogged[33];
  55. public plugin_init() {
  56. register_plugin("PsychoStats PIP", ps_version, "Stormtrooper");
  57. register_cvar("ps_version", ps_version);
  58. register_cvar("ps_db_host","127.0.0.1");
  59. register_cvar("ps_db_user","ps2");
  60. register_cvar("ps_db_pass","ps2");
  61. register_cvar("ps_db_name","ps_stats");
  62. register_cvar("ps_db_plrtable","pstats_plr");
  63. register_cvar("ps_stats_url","");
  64. register_cvar("ps_rank_url","");
  65. register_cvar("ps_uniqueid","worldid");
  66. register_cvar("ps_admin_password","");
  67. register_cvar("ps_logip","1");
  68. register_concmd("ps_password", "cmdPassword", 0, "[<old password>] <new password> - sets your password in the
  69. PsychoStats database");
  70. register_concmd("ps_setadmin", "cmdSetAdmin", ADMIN_RCON, "<admin password> - sets you as ADMIN in the Psychostats
  71. database");
  72. register_concmd("ps_admin",    "cmdSetAdmin", ADMIN_RCON, "<admin password> - sets you as ADMIN in the Psychostats
  73. database");
  74. register_concmd("ps_username", "cmdUsername", 0, "<password> <new username> - sets your username in the PsychoStats
  75. database");
  76. register_clcmd("say", "HandleSay");
  77. #if defined AMXX_VERSION
  78. new configsDir[128];
  79. get_configsdir(configsDir, 127);
  80. server_cmd("exec %s/psychostats2.cfg", configsDir);
  81. #else
  82. server_cmd("exec addons/amx/psychostats2.cfg");
  83. #endif
  84. }
  85. //Called by ps_setadmin, to give yourself admin access on the stats.
  86. public cmdSetAdmin(id,level,cid) {
  87. if (!cmd_access(id,level,cid,2)) return PLUGIN_HANDLED;
  88. new cmd[128], error[256], plrmatch[65], authid[33], name[65], ipaddr[16], plrid[16], plrprofid[16], userpw[65];
  89. load_pscvars();     // Load our config
  90. read_argv(1, userpw, 64);   // Get the password specified by the user
  91. // Load the user information
  92. _getuserinfo(id, authid, name, ipaddr, plrmatch);
  93. if (equal(psadminpw, "")) {
  94.   console_print(id, "[PsychoStats] Server admin has disabled this feature.");
  95.   return PLUGIN_HANDLED;
  96. }
  97. console_print(id, "[PsychoStats] Setting ADMIN flag for %s '%s'", psuniqueid, plrmatch);
  98. if (!equal(psadminpw,userpw)) {
  99.   console_print(id, "[PsychoStats] Invalid admin password.");
  100.   return PLUGIN_HANDLED;
  101. }
  102. // Connect to mysql server
  103. #if defined AMXX_VERSION
  104. new Sql:dbh = dbi_connect(pshost, psuser, pspass, psdb, error, 255);
  105. new Result:result
  106. if (dbh <= SQL_FAILED ) {
  107. #else
  108. new dbh = mysql_connect(pshost, psuser, pspass, psdb, error, 255);
  109. if (dbh < 1) {
  110. #endif
  111.   console_print(id, "[PsychoStats] MYSQL connect error. Contact your admin: '%s'", error);
  112.   server_print("[PsychoStats] MYSQL connect error: '%s' (%s,%s,%s)", error, pshost, psuser, psdb);
  113.   return PLUGIN_HANDLED;
  114. }
  115. format(cmd, 127, "SELECT plrid FROM %s WHERE %s='%s'", plrtbl, psuniqueid, plrmatch);
  116. #if defined AMXX_VERSION
  117. if ( (result = _query(dbh, cmd, id)) == RESULT_FAILED  ) return PLUGIN_HANDLED;
  118. if (dbi_nextrow(result) > 0) {
  119.   dbi_field(result, 1, plrid, 15);  // Player ID matching the STEAMID
  120. }
  121. dbi_free_result(result)
  122. #else
  123. if (!_query(dbh, cmd, id)) return PLUGIN_HANDLED;
  124. if (mysql_nextrow(dbh) > 0) {
  125.   mysql_getfield(dbh, 1, plrid, 15);  // Player ID matching the STEAMID
  126. }
  127. #endif
  128. // If no plrid was returned then there is no match in the database for the current user
  129. if (equal(plrid,"")) {
  130.   console_print(id, "[PsychoStats] No player matches your %s '%s' in the database yet.", psuniqueid, plrmatch);
  131.   console_print(id, "[PsychoStats] Please try again after the server stats have updated.");
  132.   return PLUGIN_HANDLED;
  133. }
  134. format(cmd,127,"SELECT plrprofileid FROM %s_profile WHERE %s='%s' LIMIT 1", plrtbl, psuniqueid, plrmatch);
  135. #if defined AMXX_VERSION
  136. if ( (result = _query(dbh, cmd, id)) == RESULT_FAILED  ) return PLUGIN_HANDLED;
  137. if (dbi_nextrow(result) > 0) {
  138.   dbi_field(result, 1, plrprofid, 15);
  139. }
  140. dbi_free_result(result)
  141. #else
  142. if (!_query(dbh, cmd, id)) return PLUGIN_HANDLED;
  143. if (mysql_nextrow(dbh) > 0) {
  144.   mysql_getfield(dbh, 1, plrprofid, 15);
  145. }
  146. #endif
  147. if (equal(plrprofid,"")) {
  148.   quote_sql(name,64);
  149.   if (equal(psuniqueid,"name")) {
  150.    format(cmd,127,"INSERT INTO %s_profile (name, accesslevel) VALUES ('%s', 10)", plrtbl, name);
  151.   }
  152.   else {
  153.    format(cmd,127,"INSERT INTO %s_profile (%s, name, accesslevel) VALUES ('%s', '%s', 10)", plrtbl,
  154. psuniqueid, plrmatch, name);
  155.   }
  156. }
  157. else {
  158.   format(cmd,127,"UPDATE %s_profile SET accesslevel=10 WHERE plrprofileid='%s'", plrtbl, plrprofid);
  159. }
  160. #if defined AMXX_VERSION
  161. if ( (result = _query(dbh, cmd, id)) == RESULT_FAILED ) return PLUGIN_HANDLED;
  162. #else
  163. if (!_query(dbh, cmd, id)) return PLUGIN_HANDLED;
  164. #endif
  165. console_print(id, "[PsychoStats] Accesslevel successfully updated for %s", plrmatch);
  166. if (!equal(psurl,"")) console_print(id, "[PsychoStats] Game Stats: %s", psurl);
  167. #if defined AMXX_VERSION
  168. dbi_close(dbh);
  169. #else
  170. mysql_close(dbh);
  171. #endif
  172. return PLUGIN_HANDLED;
  173. }
  174. //Called by ps_username, to assign a username to a player profile
  175. public cmdUsername(id,level,cid) {
  176. if (!cmd_access(id,level,cid,2)) return PLUGIN_HANDLED;
  177. new cmd[256], error[256], plrmatch[65], authid[33], name[65], ipaddr[16], plrid[16], curpw[33], username[65];
  178. new sqlpw[33], pwhash[33], dbpw[33], sqluser[71];
  179. load_pscvars();     // Load our config
  180. // Load the user information
  181. _getuserinfo(id, authid, name, ipaddr, plrmatch);
  182. new args = read_argc() - 1;  // Total arg's given
  183. if (args > 1) {    // If we got more than 1 we have <old> <new>
  184.   read_argv(1, curpw, 32);
  185.   read_argv(2, username, 64);
  186. }
  187. else {     // we only have 1
  188.   console_print(id, "[PsychoStats] You must provide your password and new username.");
  189.   return PLUGIN_HANDLED;
  190. }
  191. console_print(id, "[PsychoStats] Changing username for %s '%s'", psuniqueid, plrmatch);
  192. // Connect to mysql server
  193. #if defined AMXX_VERSION
  194. new Sql:dbh = dbi_connect(pshost, psuser, pspass, psdb, error, 255);
  195. new Result:result
  196. if (dbh <= SQL_FAILED ) {
  197. #else
  198. new dbh = mysql_connect(pshost, psuser, pspass, psdb, error, 255);
  199. if (dbh < 1) {
  200. #endif
  201.   console_print(id, "[PsychoStats] MYSQL connect error. Contact your admin: '%s'", error);
  202.   server_print("[PsychoStats] MYSQL connect error: '%s' (%s,%s,%s)", error, pshost, psuser, psdb);
  203.   return PLUGIN_HANDLED;
  204. }
  205. // determine if the username specified already exists or not
  206. copy(sqluser,70,username);
  207. quote_sql(sqluser, 70);
  208. format(cmd, 255, "SELECT plrprofileid FROM %s_profile WHERE `username`='%s' LIMIT 1", plrtbl, sqluser);
  209. #if defined AMXX_VERSION
  210. if ( (result = _query(dbh, cmd, id)) == RESULT_FAILED ) return PLUGIN_HANDLED;
  211. if (dbi_nextrow(result) > 0) {
  212.   dbi_field(result, 1, plrid, 16);  // Player ID matching the STEAMID
  213. }
  214. dbi_free_result(result)
  215. #else
  216. if (!_query(dbh, cmd, id)) return PLUGIN_HANDLED;
  217. if (mysql_nextrow(dbh) > 0) {
  218.   mysql_getfield(dbh, 1, plrid, 16);  // Player ID matching the STEAMID
  219. }
  220. #endif
  221. if (!equal(plrid,"")) {
  222.   console_print(id, "[PsychoStats] Username '%s' already exists. Please try another name.", username);
  223.   return PLUGIN_HANDLED;
  224. }
  225. // Since I don't know of any md5 functions in the AMX code, i'll just let the SQL server do it for me
  226. // We're converting the curpw that the user gave into a hash so we can compare it with the current pw
  227. // We also load the current password for the user here
  228. copy(sqlpw,32,curpw);
  229. quote_sql(sqlpw, 32);
  230. format(cmd, 255, "SELECT plrprofileid, `password`, MD5('%s') as pw FROM %s_profile WHERE %s='%s' LIMIT 1", sqlpw,
  231. plrtbl, psuniqueid, plrmatch);
  232. #if defined AMXX_VERSION
  233. if ( (result = _query(dbh, cmd, id)) == RESULT_FAILED ) return PLUGIN_HANDLED;
  234. if (dbi_nextrow(result) > 0) {
  235.   dbi_field(result, 1, plrid, 16);  // Player ID matching the STEAMID
  236.   dbi_field(result, 2, dbpw, 32);  // user's current pw (might be blank)
  237.   dbi_field(result, 3, pwhash, 32);  // the converted curpw (it's an md5 hash now)
  238. }
  239. dbi_free_result(result)
  240. #else
  241. if (!_query(dbh, cmd, id)) return PLUGIN_HANDLED;
  242. if (mysql_nextrow(dbh) > 0) {
  243.   mysql_getfield(dbh, 1, plrid, 16);  // Player ID matching the STEAMID
  244.   mysql_getfield(dbh, 2, dbpw, 32);  // user's current pw (might be blank)
  245.   mysql_getfield(dbh, 3, pwhash, 32);  // the converted curpw (it's an md5 hash now)
  246. }
  247. #endif
  248. // If no plrid was returned then there is no match in the database for the current user
  249. if (equal(plrid,"")) {
  250.   console_print(id, "[PsychoStats] No player matches your %s '%s' in the database yet.", psuniqueid, plrmatch);
  251.   console_print(id, "[PsychoStats] Please create profile first using command 'ps_password'.");
  252.   return PLUGIN_HANDLED;
  253. }
  254. // we must verify they supplied a valid password
  255. if (!equali(pwhash, dbpw)) { // both pw's are md5 hashes
  256.   console_print(id, "[PsychoStats] Authentication failure for %s", authid);
  257.   console_print(id, "[PsychoStats] Passwords do not match!");
  258.   console_print(id, "[PsychoStats] Usage: ps_username <password> <new username>");
  259.   return PLUGIN_HANDLED;
  260. }
  261. copy(sqluser,70,username);
  262. quote_sql(sqluser, 70);
  263. format(cmd,255,"UPDATE %s_profile SET `username`='%s' WHERE plrprofileid='%s'", plrtbl, sqluser, plrid);
  264. #if defined AMXX_VERSION
  265. if ( (result = _query(dbh, cmd, id)) == RESULT_FAILED ) return PLUGIN_HANDLED;
  266. #else
  267. if (!_query(dbh, cmd, id)) return PLUGIN_HANDLED;
  268. #endif
  269. console_print(id, "[PsychoStats] Username successfully updated for %s '%s'", psuniqueid, plrmatch);
  270. if (!equal(psurl,"")) console_print(id, "[PsychoStats] Game Stats: %s", psurl);
  271. #if defined AMXX_VERSION
  272. dbi_close(dbh);
  273. #else
  274. mysql_close(dbh);
  275. #endif
  276. return PLUGIN_HANDLED;
  277. }
  278. //Called by ps_password, clients can set thier stats password
  279. public cmdPassword(id,level,cid) {
  280. if (!cmd_access(id,level,cid,2)) return PLUGIN_HANDLED;
  281. new cmd[256], error[256], plrmatch[65], authid[33], name[65], ipaddr[16], plrid[16], plrprofid[16], oldpw[33], curpw
  282. [33], newpw[33];
  283. new sqlpw[33];
  284. load_pscvars();     // Load our config
  285. // Load the user information
  286. _getuserinfo(id, authid, name, ipaddr, plrmatch);
  287. new args = read_argc() - 1;  // Total arg's given
  288. if (args > 1) {    // If we got more than 1 we have <old> <new>
  289.   read_argv(1, oldpw, 32);
  290.   read_argv(2, newpw, 32);
  291. }
  292. else {     // we only have 1
  293.   read_argv(1, newpw, 32);
  294. }
  295. new msg[255];
  296. msg = (args == 1) ? "[PsychoStats] Setting initial user password for player matching %s '%s'" : "[PsychoStats]
  297. Changing password for player matching %s '%s'";
  298. console_print(id, msg, psuniqueid, plrmatch);
  299. // Connect to mysql server
  300. #if defined AMXX_VERSION
  301. new Sql:dbh = dbi_connect(pshost, psuser, pspass, psdb, error, 255);
  302. new Result:result
  303. if (dbh <= SQL_FAILED ) {
  304. #else
  305. new dbh = mysql_connect(pshost, psuser, pspass, psdb, error, 255);
  306. if (dbh < 1) {
  307. #endif
  308.   console_print(id, "[PsychoStats] MYSQL connect error. Contact your admin: '%s'", error);
  309.   server_print("[PsychoStats] MYSQL connect error: '%s' (%s,%s,%s)", error, pshost, psuser, psdb);
  310.   return PLUGIN_HANDLED;
  311. }
  312. format(cmd, 255, "SELECT plrid FROM %s WHERE %s='%s' LIMIT 1", plrtbl, psuniqueid, plrmatch);
  313. #if defined AMXX_VERSION
  314. if ( (result = _query(dbh, cmd, id)) == RESULT_FAILED ) return PLUGIN_HANDLED;
  315. if (dbi_nextrow(result) > 0) {
  316.   dbi_field(result, 1, plrid, 16);  // Player ID matching the STEAMID
  317. }
  318. dbi_free_result(result);
  319. #else
  320. if (!_query(dbh, cmd, id)) return PLUGIN_HANDLED;
  321. if (mysql_nextrow(dbh) > 0) {
  322.   mysql_getfield(dbh, 1, plrid, 16);  // Player ID matching the STEAMID
  323. }
  324. #endif
  325. // If no plrid was returned then there is no match in the database for the current user
  326. if (equal(plrid,"")) {
  327.   console_print(id, "[PsychoStats] No player matches your %s '%s' in the database yet.", psuniqueid, plrmatch);
  328.   console_print(id, "[PsychoStats] Please try again after the server stats have updated.");
  329.   return PLUGIN_HANDLED;
  330. }
  331. // Since I don't know of any md5 functions in the AMX code, i'll just let the SQL server do it for me
  332. // We're converting the oldpw that the user gave into a hash so we can compare it with the current pw
  333. // We also load the current password for the user here
  334. copy(sqlpw,32,oldpw);
  335. quote_sql(sqlpw, 32);
  336. format(cmd, 255, "SELECT plrprofileid, `password`, MD5('%s') AS pw FROM %s_profile WHERE %s='%s' LIMIT 1", sqlpw,
  337. plrtbl, psuniqueid, plrmatch);
  338. #if defined AMXX_VERSION
  339. if ( (result = _query(dbh, cmd, id)) == RESULT_FAILED ) return PLUGIN_HANDLED;
  340. if (dbi_nextrow(result) > 0) {
  341.   dbi_field(result, 1, plrprofid, 16);  // Player ID matching the STEAMID
  342.   dbi_field(result, 2, curpw, 32);  // user's current pw (might be blank)
  343.   dbi_field(result, 3, oldpw, 32);  // the converted oldpw (it's an md5 hash now)
  344. }
  345. dbi_free_result(result);
  346. #else
  347. if (!_query(dbh, cmd, id)) return PLUGIN_HANDLED;
  348. if (mysql_nextrow(dbh) > 0) {
  349.   mysql_getfield(dbh, 1, plrprofid, 16);  // Player ID matching the STEAMID
  350.   mysql_getfield(dbh, 2, curpw, 32);  // user's current pw (might be blank)
  351.   mysql_getfield(dbh, 3, oldpw, 32);  // the converted oldpw (it's an md5 hash now)
  352. }
  353. #endif
  354. // If there's a current password for the user we must verify they supplied a valid password
  355. if (!equal(curpw, "")) {
  356.   if (args == 1) {
  357.    console_print(id, "[PsychoStats] Authentication failure for %s", authid);
  358.    console_print(id, "[PsychoStats] You must provide your current password in order to change it. If you
  359. don't know what it is please contact your admin.");
  360.    console_print(id, "[PsychoStats] Usage:  %s %s", "ps_password", "<old password> <new password>")
  361.    return PLUGIN_HANDLED;
  362.   }
  363.   else if (!equali(curpw, oldpw)) { // both pw's are md5 hashes
  364.    console_print(id, "[PsychoStats] Authentication failure for %s", authid);
  365.    console_print(id, "[PsychoStats] Passwords do not match!");
  366.    console_print(id, "[PsychoStats] Usage:  %s %s", "ps_password", "[<old password>] <new password>")
  367.    return PLUGIN_HANDLED;
  368.   }
  369. }
  370. copy(sqlpw,32,newpw);
  371. quote_sql(sqlpw, 32);
  372. if (equal(plrprofid,"")) {
  373.   quote_sql(name,64);
  374.   if (equal(psuniqueid,"name")) {
  375.    format(cmd,255,"INSERT INTO %s_profile (name, password, accesslevel) VALUES ('%s', MD5('%s'), '1')",
  376. plrtbl, name, sqlpw);
  377.   }
  378.   else {
  379.    format(cmd,255,"INSERT INTO %s_profile (%s, name, password, accesslevel) VALUES ('%s', '%s', MD5('%
  380. s'), '1')", plrtbl, psuniqueid, plrmatch, name, sqlpw);
  381.   }
  382. }
  383. else {
  384.   format(cmd,255,"UPDATE %s_profile SET `password`=MD5('%s') WHERE plrprofileid='%s'", plrtbl, sqlpw,
  385. plrprofid);
  386. }
  387. #if defined AMXX_VERSION
  388. if ( (result = _query(dbh, cmd, id)) == RESULT_FAILED ) return PLUGIN_HANDLED;
  389. #else
  390. if (!_query(dbh, cmd, id)) return PLUGIN_HANDLED;
  391. #endif
  392. console_print(id, "[PsychoStats] Password successfully updated for %s '%s'", psuniqueid, plrmatch);
  393. if (!equal(psurl,"")) console_print(id, "[PsychoStats] Game Stats: %s", psurl);
  394. #if defined AMXX_VERSION
  395. dbi_close(dbh);
  396. #else
  397. mysql_close(dbh);
  398. #endif
  399. return PLUGIN_HANDLED;
  400. }
  401. //This code is all for the PSRank in game MOTD popups
  402. public HandleSay(id) {
  403. new Speech[128];
  404. read_args(Speech,127);
  405. remove_quotes(Speech);
  406. load_pscvars();
  407. /*
  408. register_clcmd("say /statsme","cmdStatsMe",0,"- displays your stats")
  409. register_clcmd("say /stats","cmdStats",0,"- displays others stats")
  410. register_clcmd("say /top15","cmdTop15",0,"- displays top 15 players")
  411. register_clcmd("say /rank","cmdRank",0,"- displays your server stats")
  412. */
  413. if(containi(Speech, "/psstats") == 0) {
  414.   show_motd(id, psrankurl, "Stats: Powered by PsychoStats");
  415.   return PLUGIN_HANDLED;
  416. }
  417. if(containi(Speech, "/pstop15") == 0 || containi(Speech, "/pstop10") == 0) {
  418.   new smalltt[256];
  419.   format (smalltt,255,"%s/smalltopten.php",psrankurl);
  420.   show_motd(id, smalltt, "Top 10: Powered by PsychoStats");
  421.   return PLUGIN_HANDLED;
  422. }
  423. if(containi(Speech, "/psrank") == 0 || containi(Speech, "/psstatsme") == 0) {
  424.   new cmd[128], error[255], rankurl[256], plrmatch[65], authid[33], name[65], ipaddr[16], plrid[16];
  425.   _getuserinfo(id, authid, name, ipaddr, plrmatch);
  426.   // Connect to mysql server
  427.   #if defined AMXX_VERSION
  428.   new Sql:dbh = dbi_connect(pshost, psuser, pspass, psdb, error, 255);
  429.   new Result:result
  430.   if (dbh <= SQL_FAILED ) {
  431.   #else
  432.   new dbh = mysql_connect(pshost, psuser, pspass, psdb, error, 255);
  433.   if (dbh < 1) {
  434.   #endif
  435.    console_print(id, "[PsychoStats] MYSQL connect error. Contact your admin: '%s'", error);
  436.    server_print("[PsychoStats] MYSQL connect error: '%s' (%s,%s,%s)", error, pshost, psuser, psdb);
  437.    return PLUGIN_HANDLED;
  438.   }
  439.   format(cmd, 127, "SELECT plrid FROM %s WHERE %s='%s'", plrtbl, psuniqueid, plrmatch);
  440.   #if defined AMXX_VERSION
  441.   if ( (result = _query(dbh, cmd, id)) == RESULT_FAILED ) return PLUGIN_HANDLED;
  442.   if (dbi_nextrow(result) > 0) {
  443.    dbi_field(result, 1, plrid, 15);
  444.   }
  445.   dbi_free_result(result);
  446.   #else
  447.   if (!_query(dbh, cmd, id)) return PLUGIN_HANDLED;
  448.   if (mysql_nextrow(dbh) > 0) {
  449.    mysql_getfield(dbh, 1, plrid, 15);
  450.   }
  451.   #endif
  452.   if (equal(plrid,"")) {
  453.    client_print(id,print_chat,"[PsychoStats] No player matches your %s '%s' in the database.",
  454. psuniqueid, plrmatch);
  455.    format(rankurl,255,"%s/index.php?search=%s",psrankurl, plrmatch);
  456.   }
  457.   else {
  458.    format(rankurl,255,"%s/player.php?id=%s",psrankurl,plrid);
  459.   }
  460.   show_motd(id, rankurl, "Rank: Powered by PsychoStats")
  461.   return PLUGIN_HANDLED;
  462. }
  463. if(containi(Speech, "/search") == 0) {
  464.   new arg1[32], arg2[32];
  465.   parse(Speech,arg1,31,arg2,31);
  466.   new rankurl[256];
  467.   format(rankurl,255,"%s/index.php?search=%s",psrankurl,arg2);
  468.   show_motd(id, rankurl, "Stats Search: Powered by PsychoStats");
  469.   return PLUGIN_HANDLED;
  470. }
  471. return PLUGIN_CONTINUE;
  472. }
  473. //Below is all code to assist in IP tracking and make it more reliable
  474. public logip(id) {
  475. if (!plriplogged[id] && get_cvar_num("ps_logip")) {
  476.   new name[32], authid[32], team[32], address[32]
  477.   get_user_name(id,name,31);
  478.   get_user_authid(id,authid,31);
  479.   get_user_team(id,team,31);
  480.   get_user_ip(id,address,31);
  481.   if (equal(authid,"STEAM_ID_PENDING")) return
  482.   if (get_user_userid(id) == -1) return
  483.   if (equal(address,"")) return
  484.   if (equal(team, "UNASSIGNED")) copy(team,31,"")
  485.   log_message("^"%s<%d><%s><%s>^" triggered ^"address^" (address ^"%s^")",
  486.   name,get_user_userid(id),authid,team,address);
  487.   plriplogged[id] = 1;
  488. }
  489. }
  490. public client_disconnect(id) {
  491. //Only need to log it agian if the user did something on the server
  492. if ((get_user_frags(id) > 0) || (get_user_deaths(id) > 0) || (get_user_time(id,1) > 30)) {
  493.   //Set to 0 to make it log it agian
  494.   plriplogged[id] = 0;
  495.   logip(id);
  496. }
  497. //Set to 0 to make sure next client with this id gets logged
  498. plriplogged[id] = 0;
  499. }
  500. public client_connect(id) {
  501. plriplogged[id] = 0;
  502. }
  503. public client_putinserver(id) {
  504. logip(id);
  505. }
  506. public client_infochanged(id) {
  507. logip(id);
  508. }
  509. // Support functions
  510. // This can be called from another function to load the cvars into variables
  511. load_pscvars() {
  512. get_cvar_string("ps_db_host", pshost, 63);
  513. get_cvar_string("ps_db_user", psuser, 31);
  514. get_cvar_string("ps_db_pass", pspass, 31);
  515. get_cvar_string("ps_db_name", psdb, 31);
  516. get_cvar_string("ps_db_plrtable", plrtbl, 31);
  517. get_cvar_string("ps_stats_url", psurl, 254);
  518. get_cvar_string("ps_rank_url", psrankurl, 254);
  519. get_cvar_string("ps_admin_password", psadminpw, 63);
  520. get_cvar_string("ps_uniqueid", psuniqueid, 15);
  521. if (equal(psrankurl,"")) copy(psrankurl, 254, psurl);
  522. }
  523. // Load the users information
  524. public _getuserinfo(id, authid[33], name[65], ipaddr[16], plrmatch[65]) {
  525. #if defined DEBUG
  526. copy(authid, 32, debug_authid);
  527. copy(name, 32, debug_name);
  528. copy(ipaddr, 15, debug_ipaddr);
  529. #else
  530. get_user_authid(id, authid, 32);
  531. get_user_name(id, name, 32);
  532. get_user_ip(id, ipaddr, 15, 1);  // 1 = do not include port
  533. #endif
  534. // Determine which field we want to match players on and store it in 'plrmatch'
  535. if (equali(psuniqueid, "name")) {
  536.   copy(plrmatch, 32, name);
  537.   quote_sql(plrmatch,64);
  538. }
  539. else if (equali(psuniqueid, "ipaddr")) {
  540.   copy(plrmatch, 15, ipaddr);
  541. }
  542. else {  // always default to 'worldid'
  543.   copy(plrmatch, 33, authid);
  544. }
  545. }
  546. // short-cut function for performing a mysql_query. Returns false on error.
  547. #if defined AMXX_VERSION
  548. public Result:_query(Sql:dbh, cmd[], id) {
  549. new Result:result = dbi_query(dbh, cmd)
  550. if (result == RESULT_FAILED) {
  551.   new error[255];
  552.   dbi_error(dbh, error, 254);
  553.   console_print(id, "[PsychoStats] SQL error. Contact your admin: '%s'", error);
  554.   server_print("[PsychoStats] SQL error: '%s' (%s,%s,%s)", error, pshost, psuser, psdb);
  555. }
  556. return result;
  557. }
  558. #else
  559. public _query(dbh, cmd[], id) {
  560. if (mysql_query(dbh, cmd) < 1) {
  561.   new error[255];
  562.   mysql_error(dbh, error, 254);
  563.   console_print(id, "[PsychoStats] SQL error. Contact your admin: '%s'", error);
  564.   server_print("[PsychoStats] SQL error: '%s' (%s,%s,%s)", error, pshost, psuser, psdb);
  565.   return false;
  566. }
  567. return true;
  568. }
  569. #endif
  570. // quotes the string given to be used safely in a mysql_query() call
  571. quote_sql(string[],len) {
  572. new charnum = 0;
  573. while ( replace( string[charnum] ,len,"'","\'") != 0) {
  574.   charnum += contain(string[charnum],"\'") + 2;
  575. }
  576. charnum = 0;
  577. while ( replace( string[charnum] ,len,"`","\`") != 0) {
  578.   charnum += contain(string[charnum],"\`") + 2;
  579. }
  580. }
复制代码

PS:该问题的出现也是由于系统Bug造成的,运行ps_password命令时PIP插件默认对pstats_plr表进行操作,但是该表根本没有password这一列
,有人将pstats_plr修改为pstats_plr_profile则会报找不到plrid这一列。这一问题即使是将Psychostats升级到最新版本也无法解决。
Stormtrooper的回复是他目前正忙于3.0的开发,没时间解决这个问题*_*||。以上代码已经修复该问题。

【小技巧】
有的朋友可能在安装theme时比较头疼,覆盖来覆盖去的总是显示有问题。其实只需要将下载的theme解压缩到PS安装目录下的themes文件夹下,然后运行install.pl -step web theme,在选择theme时就会多出一个选项(不只是psweb了)。如将psmod解压到themes文件夹下的psmod文件夹下,运行install.pl -step web theme时就会让你选择按装psweb还是psmod了。在重新安装theme后可能Q1还会出现,依法解决就可以了。


待续……
 楼主| 发表于 2006-6-25 13:28:02 | 显示全部楼层 来自 天津

回复: [技术类][原创]Psychostats2.3.3安装之十全大补贴

花了好长时间查找资料整理的,希望大家多多支持!
回复

使用道具 举报

发表于 2006-6-25 13:28:41 | 显示全部楼层 来自 重庆永川区

回复: [技术类][原创]Psychostats2.3.3安装之十全大补贴

看看先....................
回复

使用道具 举报

发表于 2006-6-25 18:21:54 | 显示全部楼层 来自 陕西咸阳

回复: [技术类][原创]Psychostats2.3.3安装之十全大补贴

建议斑竹加精。。。。。
回复

使用道具 举报

发表于 2006-6-25 21:18:43 | 显示全部楼层 来自 云南曲靖

回复: [技术类][原创]Psychostats2.3.3安装之十全大补贴

支持原创!做个视频教程吧!
回复

使用道具 举报

 楼主| 发表于 2006-6-25 21:37:13 | 显示全部楼层 来自 天津

回复: [技术类][原创]Psychostats2.3.3安装之十全大补贴

谢谢支持!
但是做完了放在哪啊?
回复

使用道具 举报

发表于 2006-6-25 22:40:53 | 显示全部楼层 来自 云南曲靖

回复: [技术类][原创]Psychostats2.3.3安装之十全大补贴

Post by cfans
谢谢支持!
但是做完了放在哪啊?


做好后,请联系我,空间你放心!
回复

使用道具 举报

发表于 2006-6-25 23:06:02 | 显示全部楼层 来自 广东东莞

回复: [技术类][原创]Psychostats2.3.3安装之十全大补贴

看看先,不错的东东!
回复

使用道具 举报

发表于 2006-6-26 14:09:38 | 显示全部楼层 来自 江苏南京

回复: [技术类][原创]Psychostats2.3.3安装之十全大补贴

看看:D :sweet_kis
回复

使用道具 举报

发表于 2006-6-26 15:01:35 | 显示全部楼层 来自 陕西西安

回复: [技术类][原创]Psychostats2.3.3安装之十全大补贴

如果需要空间的话,联系我也可以:)
回复

使用道具 举报

游客
回复
您需要登录后才可以回帖 登录 | 注个册吧

快速回复 返回顶部 返回列表