diff --git a/smserver/controllers/legacy/game_over.py b/smserver/controllers/legacy/game_over.py index 59f172a..3df99cf 100644 --- a/smserver/controllers/legacy/game_over.py +++ b/smserver/controllers/legacy/game_over.py @@ -56,7 +56,7 @@ def create_stats(self, user, raw_stats, duration): if raw_stats["data"]: songstat.grade = raw_stats["data"][-1]["grade"] - songstat.score = raw_stats["data"][-1]["score"] + songstat.score = raw_stats["dp"] for stepid in models.SongStat.stepid.values(): setattr(songstat, stepid, 0) diff --git a/smserver/controllers/legacy/game_start_request.py b/smserver/controllers/legacy/game_start_request.py index d8cffc0..8954efc 100644 --- a/smserver/controllers/legacy/game_start_request.py +++ b/smserver/controllers/legacy/game_start_request.py @@ -38,12 +38,20 @@ def handle(self): "feet": self.packet["first_player_feet"], "difficulty": self.packet["first_player_difficulty"], "options": self.packet["first_player_options"], + "toasties": 0, + "perfect_combo": 0, + "dp": 0, + "taps": 0, "best_score": song.best_score_value(self.packet["first_player_feet"]) }, 1: {"data": [], "feet": self.packet["second_player_feet"], "difficulty": self.packet["second_player_difficulty"], "options": self.packet["second_player_options"], + "toasties": 0, + "perfect_combo": 0, + "dp": 0, + "taps": 0, "best_score": song.best_score_value(self.packet["second_player_feet"]) }, "start_at": datetime.datetime.now(), diff --git a/smserver/controllers/legacy/game_status_update.py b/smserver/controllers/legacy/game_status_update.py index d52f529..a987640 100644 --- a/smserver/controllers/legacy/game_status_update.py +++ b/smserver/controllers/legacy/game_status_update.py @@ -25,11 +25,37 @@ def handle(self): "score": self.packet["score"], "combo": self.packet["combo"], "health": self.packet["health"], + #"note_size": self.packet["note_size"], Requires smpacket update "offset": self.packet["offset"] } with self.conn.mutex: - best_score = self.conn.songstats[self.packet["player_id"]]["best_score"] + pid = self.packet["player_id"] + best_score = self.conn.songstats[pid]["best_score"] + + ''' requires smapcket update + if not stats["note_size"] or stats["note_size"] <= 0: + notesize = self.notesize_from_combo(stats["combo"], self.conn.songstats[pid]["data"]) + else: + notesize = stats["note_size"] + ''' + notesize = self.notesize_from_combo(stats["combo"], self.conn.songstats[pid]["data"]) + offset = float(stats["offset"]) / 2000.0 - 16.384 + if stats["stepid"] > 3 and stats["stepid"] < 9: + self.conn.songstats[pid]["taps"] += 1 + stats["stepid"] = models.SongStat.get_stepid(offset) + if stats["stepid"] == 7 or stats["stepid"] == 8: + self.conn.songstats[pid]["perfect_combo"] += notesize + elif stats["stepid"] == 4 or stats["stepid"] == 5 or stats["stepid"] == 6: + self.conn.songstats[pid]["perfect_combo"] = 0 + if stats["stepid"] == 3: + self.conn.songstats[pid]["perfect_combo"] = 0 + if self.conn.songstats[pid]["perfect_combo"] != 0 and self.conn.songstats[pid]["perfect_combo"] % 250 == 0: + self.conn.songstats[pid]["toasties"] += 1 + self.conn.songstats[pid]["dp"] += models.SongStat.calc_dp(stats["stepid"]) + stats["grade"] = models.SongStat.calc_grade_from_ratio( \ + self.conn.songstats[pid]["dp"] / (self.conn.songstats[pid]["taps"]*2), \ + self.conn.songstats[pid]["data"]) if best_score and stats["score"] > best_score: with self.conn.mutex: @@ -50,3 +76,13 @@ def beat_best_score(self): ) self.sendroom(self.conn.room, smpacket.SMPacketServerNSCSU(message=message)) + + + def notesize_from_combo(self, combo, data): + if len(data) > 0: + if combo > 0: + return combo - data[-1]["combo"] + else: + return 1 + else: + return 1 diff --git a/smserver/models/song_stat.py b/smserver/models/song_stat.py index e7d390f..50ad31a 100644 --- a/smserver/models/song_stat.py +++ b/smserver/models/song_stat.py @@ -200,6 +200,105 @@ def stats(self): def nb_notes(self): return sum(getattr(self, note, 0) for note in self.stepid.values()) + @staticmethod + def calc_grade(score, data): + if score >= 100.00: + for note in data: + if note["stepid"] > 2 and note["stepid"] < 9: + if note != 8: + return 1 + return 0 + elif score >= 93.00: + return 2 + elif score >= 80.00: + return 3 + elif score >= 65.00: + return 4 + elif score >= 45.00: + return 5 + return 6 + + @staticmethod + def calc_dp(stepsid): + if stepsid == 8 or stepsid == 7: + return 2 + elif stepsid == 6: + return 1 + elif stepsid == 5: + return 0 + elif stepsid == 4: + return -4 + elif stepsid == 3: + return -8 + elif stepsid == 10: + return 0 + else: + return 0 + + @staticmethod + def calc_migsp(stepsid): + if stepsid == 8: + return 3 + elif stepsid == 7: + return 2 + elif stepsid == 6: + return 1 + elif stepsid == 5: + return 0 + elif stepsid == 4: + return -4 + elif stepsid == 3: + return -8 + elif stepsid == 10: + return 6 + else: + return 0 + + #wife score aproximation + @staticmethod + def calc_wifep(offset): + avedeviation = 95.0 + maxms = offset*1000.0 + y = 1.0 - float(pow(2, (-1) * maxms*maxms / 9025.0)) + y = pow(y, 2) + return (2 + 8)*(1 - y) - 8 + + @staticmethod + def calc_grade_from_ratio(score, data): + if score >= 1: + for note in data: + if note["stepid"] > 2 and note["stepid"] < 9: + if note != 8: + return 1 + return 0 + elif score >= 0.93: + return 2 + elif score >= 0.80: + return 3 + elif score >= 0.65: + return 4 + elif score >= 0.45: + return 5 + return 6 + + # offset-> stepid + @staticmethod + def get_stepid(offset): + smarv = 0.02259; + sperf = 0.04509; + sgreat = 0.09009; + sgood = 0.13509; + sboo = 0.18909; + if (offset < smarv) and (offset > (smarv * -1.0)): + return 8 + elif (offset < sperf) and (offset > (sperf * -1.0)): + return 7 + elif (offset < sgreat) and (offset > (sgreat * -1.0)): + return 6 + elif (offset < sgood) and (offset > (sgood * -1.0)): + return 5 + else: + return 4 class BinaryStats(SMPacket): _payload = [ diff --git a/test/test_functional/test_server.py b/test/test_functional/test_server.py index dfabe97..be6f464 100644 --- a/test/test_functional/test_server.py +++ b/test/test_functional/test_server.py @@ -288,12 +288,12 @@ def test_client_bin_game_status_update(self): self.test_client_json_game_start_request() packet = smpacket.SMPacketClientNSCGSU( player_id=0, - step_id=4, - grade=3, + step_id=8, + grade=0, score=50000, combo=1, health=50, - offset=20000, + offset=32760, ) self.client_bin.on_data(packet.binary) @@ -301,8 +301,8 @@ def test_client_bin_game_status_update(self): songstats = self.client_bin.songstats self.assertEqual(len(songstats[0]["data"]), 1) - self.assertEqual(songstats[0]["data"][0]["stepid"], 4) - self.assertEqual(songstats[0]["data"][0]["grade"], 3) + self.assertEqual(songstats[0]["data"][0]["stepid"], 8) + self.assertEqual(songstats[0]["data"][0]["grade"], 0) self.assertEqual(songstats[0]["data"][0]["score"], 50000) self.assertEqual(songstats[0]["data"][0]["combo"], 1) self.assertEqual(songstats[0]["data"][0]["health"], 50) @@ -326,8 +326,8 @@ def test_client_bin_game_over(self): songstats = list(self.session.query(models.SongStat).filter_by(user=self.user_bin1)) self.assertEqual(len(songstats), 1) - self.assertEqual(songstats[0].score, 50000) - self.assertEqual(songstats[0].grade, 3) + self.assertEqual(songstats[0].score, 4) + self.assertEqual(songstats[0].grade, 1) self.assertEqual(songstats[0].max_combo, 1) def test_client_bin_disconnect(self):