· 9 years ago · Dec 14, 2016, 04:30 AM
1Just something some people requested, so i wrote an API to handle it, which actually seems to work faster than using a direct database connection. I've also added measures to prevent injections and malicious code, so no worries ^-^
2
3Prerequisites: [Only registered and activated users can see links. Click Here To Register...]
4
5if you do not have a prestige system, then dont make use of the prestige column, but the php API i wrote uses it unless you reconfigure it.
6
7Code:
8CREATE TABLE IF NOT EXISTS `hs_users` (
9 `id` int(11) NOT NULL AUTO_INCREMENT,
10 `username` varchar(40) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
11 `rights` int(1) NOT NULL DEFAULT '0',
12 `prestige` int(1) NOT NULL DEFAULT '0',
13 `overall_xp` bigint(20) NOT NULL,
14 `attack_xp` int(11) NOT NULL,
15 `defence_xp` int(11) NOT NULL,
16 `strength_xp` int(11) NOT NULL,
17 `constitution_xp` int(11) NOT NULL,
18 `ranged_xp` int(11) NOT NULL,
19 `prayer_xp` int(11) NOT NULL,
20 `magic_xp` int(11) NOT NULL,
21 `cooking_xp` int(11) NOT NULL,
22 `woodcutting_xp` int(11) NOT NULL,
23 `fletching_xp` int(11) NOT NULL,
24 `fishing_xp` int(11) NOT NULL,
25 `firemaking_xp` int(11) NOT NULL,
26 `crafting_xp` int(11) NOT NULL,
27 `smithing_xp` int(11) NOT NULL,
28 `mining_xp` int(11) NOT NULL,
29 `herblore_xp` int(11) NOT NULL,
30 `agility_xp` int(11) NOT NULL,
31 `thieving_xp` int(11) NOT NULL,
32 `slayer_xp` int(11) NOT NULL,
33 `farming_xp` int(11) NOT NULL,
34 `runecrafting_xp` int(11) NOT NULL,
35 `hunter_xp` int(11) NOT NULL,
36 `construction_xp` int(11) NOT NULL,
37 `summoning_xp` int(11) NOT NULL,
38 `dungeoneering_xp` int(11) NOT NULL,
39 PRIMARY KEY (`id`)
40) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=0 ;
41
42You'll want to save this file as highscores.php and upload it to your webserver after you've configured it. I've left notes where stuff needs edited ;D
43Code:
44<?php
45 // This is your Server IP / VPS IP
46 $SERVER_IP = "127.0.0.1";
47
48 if (!isset($_SERVER['REMOTE_ADDR']) || empty($_SERVER['REMOTE_ADDR']) || $_SERVER['REMOTE_ADDR'] != $SERVER_IP) {
49 exit();
50 }
51
52 $array = array("username", "rights", "prestige", "overall", "attack", "defence", "strength", "constitution", "ranged", "prayer", "magic", "cooking", "woodcutting", "fletching", "fishing", "firemaking", "crafting", "smithing", "mining", "herblore", "agility", "thieving", "slayer", "farming", "runecrafting", "hunter", "construction", "summoning", "dungeoneering");
53
54 $length = count($array);
55
56 for ($i = 0; $i < count($array); $i++) {
57 if (!isset($_GET[$array[$i]])) {
58 exit();
59 }
60 }
61
62
63 // strip username of anything that doesnt match the regex (A-Z, a-z, 0-9, and Space)
64 $user = preg_replace('/[^A-Za-z0-9 \-]/', ' ', $_GET['username']);
65 $user = str_replace('_', ' ', $user); //just as a backup measure -.-
66 $user = strtolower($user); // force lowercase for whatever reason -.-
67
68 // edit the connection details below to your database
69 $con = new mysqli("host", "username", "password", "database") or die($con->$error);
70 $res = $con->query("SELECT * FROM hs_users WHERE username='".$user."'");
71
72 if ($res->num_rows > 0) {
73 $con->query("DELETE FROM hs_users WHERE username='".$user."'");
74 }
75
76 $query = "INSERT INTO hs_users (";
77
78
79 for ($i = 0; $i < $length; $i++) {
80 $skill = "".$array[$i]."";
81 if ($i > 2)
82 $skill .= "_xp";
83 $query .= "$skill".($i < $length - 1 ? ", " : "")."";
84 }
85
86 $query .= ") VALUES(";
87 for ($i = 0; $i < $length; $i++) {
88 if (!is_numeric(($i < $length - 1 ? $_GET[$array[$i + 1]] : $_GET[$array[$i]]))) {
89 exit();
90 }
91 if ($i == 0) {
92 $query .= "'".ucwords($user)."'".($i < $length-1 ? ", " : "")."";
93 } else {
94 $query .= "'".$_GET[$array[$i]]."'".($i < $length-1 ? ", " : "")."";
95 }
96 }
97
98 $query .= ")";
99 if ($con->query($query)) {
100 echo 'success';
101 } else {
102 echo 'fail';
103 }
104
105?>
106Yes it's ugly, now moving on to the server-side ;D
107
108As the comment states in the code, just edit the URL link. I've added the username parameter for my own reason, so I could do a manual mass force-update to all players when they're not even online. I'll share that code with you by itself.
109
110You can put this just about anywhere since it's called statically. I myself made a class called "Highscores.java" and slapped it there.
111
112Imports used:
113Code:
114import java.io.BufferedReader;
115import java.io.File;
116import java.io.InputStream;
117import java.io.InputStreamReader;
118import java.net.URL;
119import java.net.URLConnection;
120
121Code:
122 public static boolean updateHighscores(Player player, String username) {
123 String line = "";
124 try {
125 // you'll want to edit the link below to your website URL and approriate upload directory.
126 String query = "http://yoursite.com/highscores.php?&"+getQuery(player, username);
127 URL u = new URL(query);
128 URLConnection c = u.openConnection();
129 InputStream r = c.getInputStream();
130 BufferedReader reader = new BufferedReader(new InputStreamReader(r));
131 line = reader.readLine().trim();
132 reader.close();
133 if (line.equals("success")) {
134 if (player.isRunning()) {
135 player.sendMessage("Your highscores have been updated.");
136 }
137 System.out.println("Saved: "+player.getDisplayName());
138 return true;
139 }
140 if (player.isRunning()) {
141 player.sendMessage("Your highscores have failed to update..");
142 }
143 return false;
144 } catch (Exception e) {
145 e.printStackTrace();
146 return false;
147 }
148 }
149
150 public static String getQuery(Player player, String username) {
151 String query = "";
152 query += "username="+username+"&";
153 // if you dont have prestige, just change to prestige = 0
154 query += "rights="+player.getRights()+"&";
155 query += "prestige="+player.getPrestigeLevel()+"&";
156 query += "overall="+player.getSkills().getTotalXp()+"&";
157 for (int i = 0; i < 25; i++) {
158 query += Skills.SKILLS[i].toLowerCase()+"="+(int)player.getSkills().getXp(i)+""+(i < Skills.SKILLS.length - 1 ? "&" : "");
159 }
160 return query;
161 }
162The command I use to have players manually update their highscores is below:
163
164Code:
165if (cmd[0].equals("hs")) {
166 Highscores.updateHighscores(player, player.getUsername());
167 return true;
168}
169DO NOT FORGET IMPORTS.
170
171
172------
173Mass updating ALL players:
174
175Code:
176 public static void forceUpdates() {
177 File file = new File("data/playersaves/characters");
178 File[] files = file.listFiles();
179 for (File f : files) {
180 String name = f.getName();
181 String[] split = name.split("\\.");
182 // could also just do SerializableFilesManager.loadPlayer(split[0]); if you do not have the findPlayer method >_>
183 Player p = World.findPlayer(split[0]);
184 if (p == null) {
185 continue;
186 }
187 updateHighscores(p, split[0]);
188 }
189 }
190Also if you have any nulled playersaves, error will also show in the console when iterating through the players and it finds a nulled account.
191
192Easy Peasy
193~Fox
194[Only registered and activated users can see links. Click Here To Register...]