Guest User

Untitled

a guest
Jun 15th, 2017
17
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // Reference: Oxide.Core.MySql
  2. // Reference: Oxide.Core.SQLite
  3.  
  4. using System;
  5. using System.Collections.Generic;
  6. using Oxide.Core;
  7. using Oxide.Core.Configuration;
  8. using Oxide.Core.Libraries.Covalence;
  9. using Oxide.Core.SQLite.Libraries;
  10. using Oxide.Core.MySql.Libraries;
  11. using Newtonsoft.Json.Linq;
  12. using Oxide.Core.Database;
  13. using Newtonsoft.Json;
  14. using System.Linq;
  15.  
  16. namespace Oxide.Plugins
  17. {
  18. [Info("PlayerDatabase", "Reneb", "1.5.7", ResourceId = 1939)]
  19. class PlayerDatabase : CovalencePlugin
  20. {
  21. List<string> changedPlayersData = new List<string>();
  22.  
  23. DataType dataType = DataType.Files;
  24.  
  25. enum DataType
  26. {
  27. Files,
  28. SQLite,
  29. MySql
  30. }
  31.  
  32. ////////////////////////////////////////////////////////////
  33. // Configs
  34. ////////////////////////////////////////////////////////////
  35.  
  36. static int dataTypeCfg = 1;
  37.  
  38. static string sqlitename = "playerdatabase.db";
  39.  
  40. static string sql_host = "localhost";
  41. static int sql_port = 3306;
  42. static string sql_db = "rust";
  43. static string sql_user = "root";
  44. static string sql_pass = "toor";
  45.  
  46.  
  47. protected override void LoadDefaultConfig() { }
  48.  
  49. private void CheckCfg<T>(string Key, ref T var)
  50. {
  51. if (Config[Key] is T)
  52. var = (T)Config[Key];
  53. else
  54. Config[Key] = var;
  55. }
  56.  
  57. void Init()
  58. {
  59. CheckCfg<int>("Data Type : 0 (Files) or 1 (SQLite) or 2 (MySQL)", ref dataTypeCfg);
  60. CheckCfg<string>("SQLite - Database Name", ref sqlitename);
  61. CheckCfg<string>("MySQL - Host", ref sql_host);
  62. CheckCfg<int>("MySQL - Port", ref sql_port);
  63. CheckCfg<string>("MySQL - Database Name", ref sql_db);
  64. CheckCfg<string>("MySQL - Username", ref sql_user);
  65. CheckCfg<string>("MySQL - Password", ref sql_pass);
  66. dataType = (DataType)dataTypeCfg;
  67. SaveConfig();
  68. SetupDatabase();
  69. }
  70.  
  71. ////////////////////////////////////////////////////////////
  72. // General Methods
  73. ////////////////////////////////////////////////////////////
  74.  
  75. void FatalError(string msg)
  76. {
  77. Interface.Oxide.LogError(msg);
  78. if (dataType == DataType.MySql) Sql_conn.Con.Close();
  79. timer.Once(0.01f, () => Interface.Oxide.UnloadPlugin("PlayerDatabase"));
  80. }
  81.  
  82. string GetMsg(string key, object steamid = null) => lang.GetMessage(key, this, steamid == null ? null : steamid.ToString());
  83.  
  84. List<string> KnownPlayers() => dataType == DataType.SQLite ? sqliteData.Keys.ToList() : dataType == DataType.MySql ? sqlData.Keys.ToList() : storedData.knownPlayers.ToList();
  85.  
  86. bool isKnownPlayer(string userid) => dataType == DataType.SQLite ? sqliteData.ContainsKey(userid) : dataType == DataType.MySql ? sqlData.ContainsKey(userid) : storedData.knownPlayers.Contains(userid);
  87.  
  88. List<string> GetAllKnownPlayers() => KnownPlayers();
  89.  
  90. object FindPlayer(string arg)
  91. {
  92. ulong steamid = 0L;
  93. ulong.TryParse(arg, out steamid);
  94. string lowerarg = arg.ToLower();
  95.  
  96. if (steamid != 0L && arg.Length == 17)
  97. {
  98. if (!isKnownPlayer(arg)) return GetMsg("No players found matching this steamid.", null);
  99. else return arg;
  100. }
  101. Dictionary<string, string> foundPlayers = new Dictionary<string, string>();
  102. foreach (var userid in KnownPlayers())
  103. {
  104. var d = GetPlayerData(userid, "name");
  105. if (d != null)
  106. {
  107. var name = (string)d;
  108. string lowname = name.ToLower();
  109. if (lowname.Contains(lowerarg))
  110. if (!foundPlayers.ContainsKey(userid))
  111. foundPlayers.Add(userid, name.ToString());
  112.  
  113. }
  114. }
  115. if (foundPlayers.Count > 1)
  116. {
  117. string msg = string.Empty;
  118. foreach (KeyValuePair<string, string> pair in foundPlayers) { msg += string.Format("{0} {1}\n", pair.Key, pair.Value); }
  119. return msg;
  120. }
  121. foreach (string key in foundPlayers.Keys)
  122. {
  123. return key;
  124. }
  125. return GetMsg("No players found matching this name.", null);
  126. }
  127.  
  128. ////////////////////////////////////////////////////////////
  129. // Oxide Hooks
  130. ////////////////////////////////////////////////////////////
  131.  
  132. void OnServerSave()
  133. {
  134. SavePlayerDatabase();
  135.  
  136. if (dataType == DataType.Files) SaveKnownPlayers();
  137. }
  138.  
  139. void Unload()
  140. {
  141. OnServerSave();
  142. }
  143.  
  144. void SetupDatabase()
  145. {
  146. LoadData();
  147.  
  148. lang.RegisterMessages(new Dictionary<string, string>
  149. {
  150. { "No players found matching this steamid.", "No players found matching this steamid."},
  151. { "No players found matching this name.","No players found matching this name." }
  152. }, this);
  153. }
  154.  
  155. void OnUserConnected(IPlayer player) { OnPlayerJoined(player.Id, player.Name, player.Address); }
  156.  
  157. void OnPlayerJoined(string steamid, string name, string ip)
  158. {
  159. if (!isKnownPlayer(steamid)) { LoadPlayer(steamid); }
  160. SetPlayerData(steamid, "name", name);
  161. SetPlayerData(steamid, "ip", ip);
  162. SetPlayerData(steamid, "steamid", steamid);
  163. }
  164.  
  165. ////////////////////////////////////////////////////////////
  166. // Save/Load
  167. ////////////////////////////////////////////////////////////
  168.  
  169. void LoadData()
  170. {
  171. switch (dataType)
  172. {
  173. case DataType.SQLite:
  174. LoadSQLite();
  175. break;
  176. case DataType.MySql:
  177. LoadMySQL();
  178. break;
  179. default:
  180. LoadFiles();
  181. break;
  182. }
  183. }
  184.  
  185. void LoadPlayers()
  186. {
  187. foreach (string userid in KnownPlayers())
  188. {
  189. try
  190. {
  191. LoadPlayer(userid);
  192. }
  193. catch
  194. {
  195. Interface.Oxide.LogWarning("Couldn't load " + userid);
  196. }
  197. }
  198. }
  199.  
  200. void LoadPlayer(string userid)
  201. {
  202. try
  203. {
  204. if (dataType == DataType.SQLite)
  205. {
  206. LoadPlayerSQLite(userid);
  207. }
  208. else if (dataType == DataType.MySql)
  209. {
  210. LoadPlayerSQL(userid);
  211. }
  212. else
  213. {
  214. LoadPlayerData(userid);
  215. }
  216. }
  217. catch (Exception e)
  218. {
  219. LogError(string.Format("Loading {0} got this error: {1}", userid, e.Message));
  220. }
  221. }
  222.  
  223. void SavePlayerDatabase()
  224. {
  225. #if RUST
  226. using (TimeWarning.New("Save PlayerDatabase", 0.1f))
  227. {
  228. #endif
  229. foreach (string userid in changedPlayersData)
  230. {
  231. try
  232. {
  233. if (dataType == DataType.SQLite)
  234. {
  235. SavePlayerSQLite(userid);
  236. }
  237. else if (dataType == DataType.MySql)
  238. {
  239. SavePlayerSQL(userid);
  240. }
  241. else
  242. {
  243. SavePlayerData(userid);
  244. }
  245. }
  246. catch (Exception e)
  247. {
  248. Interface.Oxide.LogWarning(e.Message);
  249. }
  250. }
  251. changedPlayersData.Clear();
  252. #if RUST
  253. }
  254. #endif
  255. }
  256.  
  257. ////////////////////////////////////////////////////////////
  258. // Set / Get PlayerData
  259. ////////////////////////////////////////////////////////////
  260.  
  261. void SetPlayerData(string userid, string key, object data)
  262. {
  263. if (!isKnownPlayer(userid)) LoadPlayer(userid);
  264. if (dataType == DataType.SQLite)
  265. {
  266. if (!isValidColumn(key))
  267. {
  268. CreateNewColumn(key);
  269. }
  270. sqliteData[userid][key] = JsonConvert.SerializeObject(data);
  271. }
  272. else if (dataType == DataType.MySql)
  273. {
  274. if (!isValidColumn2(key))
  275. {
  276. CreateNewColumn2(key);
  277. }
  278. sqlData[userid][key] = JsonConvert.SerializeObject(data);
  279. }
  280. else
  281. {
  282. var profile = playersData[userid];
  283.  
  284. profile[key] = JsonConvert.SerializeObject(data);
  285. playersData[userid] = profile;
  286. }
  287.  
  288. if (!changedPlayersData.Contains(userid))
  289. changedPlayersData.Add(userid);
  290. }
  291.  
  292. object GetPlayerDataRaw(string userid, string key)
  293. {
  294. if (!isKnownPlayer(userid)) return null;
  295.  
  296. if (dataType == DataType.SQLite)
  297. {
  298. if (!isValidColumn(key)) return null;
  299. if (sqliteData[userid] == null) return null;
  300. if (sqliteData[userid][key] == null) return null;
  301. return (string)sqliteData[userid][key];
  302. }
  303. else if (dataType == DataType.MySql)
  304. {
  305. if (!isValidColumn2(key)) return null;
  306. if (sqlData[userid] == null) return null;
  307. if (sqlData[userid][key] == null) return null;
  308. return (string)sqlData[userid][key];
  309. }
  310. else
  311. {
  312. var profile = playersData[userid];
  313. if (profile[key] == null) return null;
  314. return (string)profile[key];
  315. }
  316. }
  317. object GetPlayerData(string userid, string key)
  318. {
  319. if (!isKnownPlayer(userid)) return null;
  320.  
  321. if (dataType == DataType.SQLite)
  322. {
  323. if (!isValidColumn(key)) return null;
  324. if (sqliteData[userid] == null) return null;
  325. if (sqliteData[userid][key] == null) return null;
  326. return JsonConvert.DeserializeObject((string)sqliteData[userid][key]);
  327. }
  328. else if (dataType == DataType.MySql)
  329. {
  330. if (!isValidColumn2(key)) return null;
  331. if (sqlData[userid] == null) return null;
  332. if (sqlData[userid][key] == null) return null;
  333. return JsonConvert.DeserializeObject((string)sqlData[userid][key]);
  334. }
  335. else
  336. {
  337. var profile = playersData[userid];
  338. if (profile[key] == null) return null;
  339. return JsonConvert.DeserializeObject((string)profile[key]);
  340. }
  341. }
  342.  
  343.  
  344. ////////////////////////////////////////////////////////////
  345. // Files
  346. ////////////////////////////////////////////////////////////
  347.  
  348. public static DataFileSystem datafile = Interface.GetMod().DataFileSystem;
  349.  
  350. string subDirectory = "playerdatabase/";
  351.  
  352. Hash<string, DynamicConfigFile> playersData = new Hash<string, DynamicConfigFile>();
  353.  
  354. StoredData storedData;
  355.  
  356. class StoredData
  357. {
  358. public HashSet<string> knownPlayers = new HashSet<string>();
  359.  
  360. public StoredData() { }
  361. }
  362.  
  363. void LoadFiles()
  364. {
  365. try
  366. {
  367. storedData = Interface.GetMod().DataFileSystem.ReadObject<StoredData>("PlayerDatabase");
  368. }
  369. catch
  370. {
  371. storedData = new StoredData();
  372. }
  373. LoadPlayers();
  374. }
  375.  
  376. void LoadPlayerData(string userid)
  377. {
  378. if (!storedData.knownPlayers.Contains(userid))
  379. storedData.knownPlayers.Add(userid);
  380.  
  381. string path = subDirectory + userid;
  382. if (datafile.ExistsDatafile(path)) { }
  383.  
  384. DynamicConfigFile profile = Interface.GetMod().DataFileSystem.GetDatafile(path);
  385.  
  386. playersData[userid] = profile;
  387. }
  388.  
  389. void SavePlayerData(string userid)
  390. {
  391. string path = subDirectory + userid;
  392. Interface.GetMod().DataFileSystem.SaveDatafile(path);
  393. }
  394.  
  395. void SaveKnownPlayers()
  396. {
  397. Interface.GetMod().DataFileSystem.WriteObject("PlayerDatabase", storedData);
  398. }
  399.  
  400. ////////////////////////////////////////////////////////////
  401. // SQLite
  402. ////////////////////////////////////////////////////////////
  403.  
  404. Core.SQLite.Libraries.SQLite Sqlite = Interface.GetMod().GetLibrary<Core.SQLite.Libraries.SQLite>();
  405. Connection Sqlite_conn;
  406.  
  407. List<string> sqliteColumns = new List<string>();
  408.  
  409. Dictionary<string, Hash<string, string>> sqliteData = new Dictionary<string, Hash<string, string>>();
  410.  
  411. bool isValidColumn(string column) => sqliteColumns.Contains(column);
  412.  
  413. void CreateNewColumn(string column)
  414. {
  415. Sqlite.Insert(Core.Database.Sql.Builder.Append(string.Format("ALTER TABLE PlayerDatabase ADD COLUMN '{0}' TEXT", column)), Sqlite_conn);
  416. sqliteColumns.Add(column);
  417. }
  418.  
  419. void LoadSQLite()
  420. {
  421. try
  422. {
  423. Sqlite_conn = Sqlite.OpenDb(sqlitename, this);
  424. if (Sqlite_conn == null)
  425. {
  426. FatalError("Couldn't open the SQLite PlayerDatabase. ");
  427. return;
  428. }
  429. Sqlite.Insert(Core.Database.Sql.Builder.Append("CREATE TABLE IF NOT EXISTS PlayerDatabase ( id INTEGER NOT NULL PRIMARY KEY UNIQUE, userid TEXT );"), Sqlite_conn);
  430. Sqlite.Query(Core.Database.Sql.Builder.Append("PRAGMA table_info(PlayerDatabase);"), Sqlite_conn, list =>
  431. {
  432. if (list == null)
  433. {
  434. FatalError("Couldn't get columns. Database might be corrupted.");
  435. return;
  436. }
  437. foreach (var entry in list)
  438. {
  439. sqliteColumns.Add((string)entry["name"]);
  440. }
  441.  
  442. });
  443. Sqlite.Query(Core.Database.Sql.Builder.Append("SELECT userid from PlayerDatabase"), Sqlite_conn, list =>
  444. {
  445. if (list == null) return;
  446. foreach (var entry in list)
  447. {
  448. string steamid = (string)entry["userid"];
  449. if (steamid != "0")
  450. {
  451. sqliteData.Add(steamid, new Hash<string, string>());
  452. }
  453. }
  454. LoadPlayers();
  455. });
  456. }
  457. catch (Exception e)
  458. {
  459. FatalError(e.Message);
  460. }
  461. }
  462.  
  463. void LoadPlayerSQLite(string userid)
  464. {
  465. if (!sqliteData.ContainsKey(userid)) { sqliteData.Add(userid, new Hash<string, string>()); }
  466. bool newplayer = true;
  467. Sqlite.Query(Core.Database.Sql.Builder.Append(string.Format("SELECT * from PlayerDatabase WHERE userid == {0}", userid)), Sqlite_conn, list =>
  468. {
  469. if (list != null)
  470. {
  471. foreach (var entry in list)
  472. {
  473. foreach (var p in entry)
  474. {
  475. if (p.Value is string)
  476. {
  477. sqliteData[userid][p.Key] = (string)p.Value;
  478. }
  479. }
  480. newplayer = false;
  481. }
  482. }
  483. if (newplayer)
  484. {
  485. sqliteData[userid]["userid"] = userid;
  486. Sqlite.Insert(Core.Database.Sql.Builder.Append(string.Format("INSERT OR REPLACE INTO PlayerDatabase ( userid ) VALUES ( {0} )", userid)), Sqlite_conn);
  487.  
  488. changedPlayersData.Add(userid);
  489. }
  490. });
  491. }
  492.  
  493. void SavePlayerSQLite(string userid)
  494. {
  495. var values = sqliteData[userid];
  496. var i = values.Count;
  497.  
  498. string arg = string.Empty;
  499. var parms = new List<object>();
  500. foreach (var c in values)
  501. {
  502. arg += string.Format("{0}`{1}` = @{2}", arg == string.Empty ? string.Empty : ",", c.Key, parms.Count.ToString());
  503. parms.Add(c.Value);
  504. }
  505.  
  506. Sqlite.Insert(Core.Database.Sql.Builder.Append(string.Format("UPDATE PlayerDatabase SET {0} WHERE userid = {1}", arg, userid), parms.ToArray()), Sqlite_conn);
  507. }
  508.  
  509.  
  510. ////////////////////////////////////////////////////////////
  511. // MySQL
  512. ////////////////////////////////////////////////////////////
  513.  
  514. Core.MySql.Libraries.MySql Sql = Interface.GetMod().GetLibrary<Core.MySql.Libraries.MySql>();
  515. Connection Sql_conn;
  516.  
  517. List<string> sqlColumns = new List<string>();
  518.  
  519. Dictionary<string, Hash<string, string>> sqlData = new Dictionary<string, Hash<string, string>>();
  520.  
  521. bool isValidColumn2(string column) => sqlColumns.Contains(column);
  522.  
  523. void CreateNewColumn2(string column)
  524. {
  525. Sql.Insert(Core.Database.Sql.Builder.Append(string.Format("ALTER TABLE `playerdatabase` ADD `{0}` LONGTEXT", column)), Sql_conn);
  526. sqlColumns.Add(column);
  527. }
  528.  
  529. void LoadMySQL()
  530. {
  531. try
  532. {
  533. Sql_conn = Sql.OpenDb(sql_host, sql_port, sql_db, sql_user, sql_pass, this);
  534. if (Sql_conn == null || Sql_conn.Con == null)
  535. {
  536. FatalError("Couldn't open the SQLite PlayerDatabase: " + Sql_conn.Con.State.ToString());
  537. return;
  538. }
  539. Sql.Insert(Core.Database.Sql.Builder.Append("CREATE TABLE IF NOT EXISTS playerdatabase ( `id` int(11) NOT NULL, `userid` VARCHAR(17) NOT NULL );"), Sql_conn);
  540. Sql.Query(Core.Database.Sql.Builder.Append("desc playerdatabase;"), Sql_conn, list =>
  541. {
  542. if (list == null)
  543. {
  544. FatalError("Couldn't get columns. Database might be corrupted.");
  545. return;
  546. }
  547. foreach (var entry in list)
  548. {
  549. sqlColumns.Add((string)entry["Field"]);
  550. }
  551.  
  552. });
  553. Sql.Query(Core.Database.Sql.Builder.Append("SELECT userid from playerdatabase"), Sql_conn, list =>
  554. {
  555. if (list == null) return;
  556. foreach (var entry in list)
  557. {
  558. string steamid = (string)entry["userid"];
  559. if (steamid != "0")
  560. sqlData.Add(steamid, new Hash<string, string>());
  561. }
  562. LoadPlayers();
  563. });
  564. }
  565. catch (Exception e)
  566. {
  567. FatalError(e.Message);
  568. }
  569. }
  570.  
  571. void LoadPlayerSQL(string userid)
  572. {
  573. if (!sqlData.ContainsKey(userid)) sqlData.Add(userid, new Hash<string, string>());
  574. bool newplayer = true;
  575. Sql.Query(Core.Database.Sql.Builder.Append(string.Format("SELECT * from playerdatabase WHERE `userid` = '{0}'", userid)), Sql_conn, list =>
  576. {
  577. if (list != null)
  578. {
  579. foreach (var entry in list)
  580. {
  581. foreach (var p in entry)
  582. {
  583. if (p.Value is string)
  584. {
  585. sqlData[userid][p.Key] = (string)p.Value;
  586. }
  587. }
  588. newplayer = false;
  589. }
  590. }
  591. if (newplayer)
  592. {
  593. sqlData[userid]["userid"] = userid;
  594. Sql.Insert(Core.Database.Sql.Builder.Append(string.Format("INSERT IGNORE INTO playerdatabase ( userid ) VALUES ( {0} )", userid)), Sql_conn);
  595.  
  596. changedPlayersData.Add(userid);
  597. }
  598. });
  599. }
  600.  
  601. void SavePlayerSQL(string userid)
  602. {
  603. var values = sqlData[userid];
  604.  
  605. string arg = string.Empty;
  606. var parms = new List<object>();
  607. foreach (var c in values)
  608. {
  609. arg += string.Format("{0}`{1}` = @{2}", arg == string.Empty ? string.Empty : ",", c.Key, parms.Count.ToString());
  610. parms.Add(c.Value);
  611. }
  612.  
  613. Sql.Insert(Core.Database.Sql.Builder.Append(string.Format("UPDATE playerdatabase SET {0} WHERE userid = {1}", arg, userid), parms.ToArray()), Sql_conn);
  614. }
  615. }
  616. }
RAW Paste Data