User ghost data and personal scores now load correctly. Not sure if area/region scores are loading or not, but personal and global scores are implemented

This commit is contained in:
skogaby
2019-01-21 18:57:28 -06:00
parent f84b9dba88
commit e02d74fafa
4 changed files with 142 additions and 9 deletions

View File

@@ -11,6 +11,7 @@ import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;
import java.time.LocalDateTime;
import java.util.List;
/**
* DAO for interacting with <code>UserSongRecord</code> objects in the database.
@@ -63,4 +64,20 @@ public class UserSongRecordDao extends AbstractHibernateDao<UserSongRecord> {
this.closeCurrentSession();
return result;
}
/**
* Finds all song records for a user.
* @param user The user of the records
* @return A list of matching records
*/
public List<UserSongRecord> findByUser(final UserProfile user) {
this.openCurrentSession();
final Query<UserSongRecord> query = this.currentSession.createQuery("from UserSongRecord where user = :user");
query.setParameter("user", user);
final List<UserSongRecord> result = query.getResultList();
this.closeCurrentSession();
return result;
}
}

View File

@@ -74,7 +74,6 @@ public class ButterflyHttpServer {
private static final ImmutableSet<String> SUPPORTED_MODULES;
// Do a static setup of our supported models, modules, etc.
// TODO: Make this not hardcoded
static {
SUPPORTED_MODELS = ImmutableSet.of("mdx_2018042300");
SUPPORTED_MODULES = ImmutableSet.of("services", "pcbtracker", "message", "facility", "pcbevent",
@@ -185,7 +184,6 @@ public class ButterflyHttpServer {
/**
* Configures the routes on the server, and the exception handlers.
* TODO: Remove all the hardcoded stuff.
*/
private void configureRoutesAndExceptions() {
// configure our root route; its handler will parse the request and go from there

View File

@@ -50,7 +50,9 @@ import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
@@ -329,7 +331,7 @@ public class PlayerDataRequestHandler extends BaseRequestHandler {
// we need to return the top score for every song/difficulty
for (Song song : SONGS_2018042300) {
for (int i = 0; i < 8; i++) {
for (int i = 0; i < 9; i++) {
if (GLOBAL_HIGH_SCORES_CACHE.get(song.getMcode()).containsKey(i)) {
record = GLOBAL_HIGH_SCORES_CACHE.get(song.getMcode()).get(i);
@@ -362,13 +364,89 @@ public class PlayerDataRequestHandler extends BaseRequestHandler {
throw new UnsupportedRequestException();
}
// TODO: Implement this properly and load/save scores... also, events probably isn't a static response
KXmlBuilder respBuilder = KXmlBuilder.create("response")
.e("playerdata")
.s32("result", 0).up()
.bool("is_new", false).up();
// insert the events
// load user scores if this was for a particular user
if (!refId.equals("X0000000000000000000000000000000")) {
// get the user's scores and sort them out so we can get the top scores
// for each song/difficulty
final List<UserSongRecord> userRecords =
this.songRecordDao.findByUser(
this.profileDao.findByUser(
this.cardDao.findByRefId(refId).getUser()));
// sort them by song and difficulty, then insert them into the response
// key for top map is the song ID
// key for the 2nd map is the difficulty
// the array: a[0] = count, a[1] = top UserSongRecord
final HashMap<Integer, HashMap<Integer, Object[]>> userTopScores = new HashMap<>();
for (UserSongRecord record : userRecords) {
if (!userTopScores.containsKey(record.getSongId())) {
userTopScores.put(record.getSongId(), new HashMap<>());
userTopScores.get(record.getSongId()).put(record.getNoteType(), new Object[] { 1, record });
} else {
if (!userTopScores.get(record.getSongId()).containsKey(record.getNoteType())) {
userTopScores.get(record.getSongId()).put(record.getNoteType(), new Object[] { 1, record });
} else {
Object[] currRecord = userTopScores.get(record.getSongId()).get(record.getNoteType());
currRecord[0] = ((Integer) currRecord[0]) + 1;
if (((UserSongRecord) currRecord[1]).getScore() < record.getScore()) {
currRecord[1] = record;
}
userTopScores.get(record.getSongId()).put(record.getNoteType(), currRecord);
}
}
}
int count = 0;
int rank = 0;
int clearkind = 0;
int score = 0;
int ghostid = 0;
// insert them into the response
for (Map.Entry<Integer, HashMap<Integer, Object[]>> entry : userTopScores.entrySet()) {
respBuilder = respBuilder.e("music")
.u32("mcode", entry.getKey()).up();
// iterate through each difficulty
for (int i = 0; i < 9; i++) {
if (entry.getValue().containsKey(i)) {
Object[] record = entry.getValue().get(i);
UserSongRecord topRecord = (UserSongRecord) record[1];
count = (Integer) record[0];
rank = topRecord.getRank();
clearkind = topRecord.getClearKind();
score = topRecord.getScore();
ghostid = ((Long) topRecord.getGhostData().getId()).intValue();
} else {
count = 0;
rank = 0;
clearkind = 0;
score = 0;
ghostid = 0;
}
respBuilder = respBuilder.e("note")
.u16("count", count).up()
.u8("rank", rank).up()
.u8("clearkind", clearkind).up()
.s32("score", score).up()
.s32("ghostid", ghostid).up().up();
}
respBuilder = respBuilder.up();
}
}
// TODO: Events probably isn't a static response
final Document document = respBuilder.getDocument();
final Element elem = respBuilder.getElement();
@@ -797,11 +875,21 @@ public class PlayerDataRequestHandler extends BaseRequestHandler {
* @return A response object for Spark
*/
private Object handleGhostLoadRequest(final int ghostId, final Request request, final Response response) {
// TODO: Store and load ghost data correctly
final KXmlBuilder builder = KXmlBuilder.create("response")
KXmlBuilder builder = KXmlBuilder.create("response")
.e("playerdata")
.s32("result", 0).up();
final GhostData ghostData = this.ghostDataDao.findById((long) ghostId);
if (ghostData != null) {
builder = builder.e("ghostdata")
.s32("code", 0).up()
.u32("mcode", ghostData.getMcode()).up()
.u8("notetype", ghostData.getNoteType()).up()
.s32("ghostsize", ghostData.getGhostData().length()).up()
.str("ghost", ghostData.getGhostData());
}
return this.sendResponse(request, response, builder);
}
@@ -918,7 +1006,7 @@ public class PlayerDataRequestHandler extends BaseRequestHandler {
int folder = XmlUtils.intAtChild(recordNode, "folder");
// construct and save
GhostData newGhostData = new GhostData(user, ghostStr);
GhostData newGhostData = new GhostData(user, ghostStr, songId, noteType);
this.ghostDataDao.create(newGhostData);
UserSongRecord newRecord = new UserSongRecord(user, playSide, playStyle, area, weight100, shopName, isPremium,

View File

@@ -37,11 +37,21 @@ public class GhostData implements Externalizable {
@Column(name = "ghost_data", columnDefinition = "TEXT")
private String ghostData;
/** The mcode of the song for this data */
@Column(name = "mcode")
private int mcode;
/** The difficulty the ghost data was for */
@Column(name = "note_type")
private int noteType;
public GhostData() { }
public GhostData(UserProfile user, String ghostData) {
public GhostData(UserProfile user, String ghostData, int mcode, int noteType) {
this.user = user;
this.ghostData = ghostData;
this.mcode = mcode;
this.noteType = noteType;
}
@Override
@@ -49,6 +59,8 @@ public class GhostData implements Externalizable {
out.writeLong(this.id);
out.writeObject(this.user);
out.writeUTF(this.ghostData);
out.writeInt(this.mcode);
out.writeInt(this.noteType);
}
@Override
@@ -56,6 +68,8 @@ public class GhostData implements Externalizable {
this.setId(in.readLong());
this.setUser((UserProfile) in.readObject());
this.setGhostData(in.readUTF());
this.setMcode(in.readInt());
this.setNoteType(in.readInt());
}
public long getId() {
@@ -81,4 +95,20 @@ public class GhostData implements Externalizable {
public void setGhostData(String ghostData) {
this.ghostData = ghostData;
}
public int getMcode() {
return mcode;
}
public void setMcode(int mcode) {
this.mcode = mcode;
}
public int getNoteType() {
return noteType;
}
public void setNoteType(int noteType) {
this.noteType = noteType;
}
}