ChatMessage.java是玩家游戏过程中的聊天信息对应的Java对象,通过解析玩家聊天信息的数据块获取。
ChatMessage.java
package com.xxg.w3gparser;
public class ChatMessage {
/**
* 发送者
*/
private Player from;
/**
* 发送方式
* 0:发送给所有玩家
* 1:发送给队友
* 2:发送给裁判或观看者
* 3+N:发送给指定玩家
*/
private long mode;
/**
* 接收者(mode为3+N时有效)
*/
private Player to;
/**
* 消息发送时间
*/
private long time;
/**
* 消息内容
*/
private String message;
public Player getFrom() {
return from;
}
public void setFrom(Player from) {
this.from = from;
}
public long getMode() {
return mode;
}
public void setMode(long mode) {
this.mode = mode;
}
public Player getTo() {
return to;
}
public void setTo(Player to) {
this.to = to;
}
public long getTime() {
return time;
}
public void setTime(long time) {
this.time = time;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
由于玩家可能在游戏过程中离开游戏,要想知道玩家的实际游戏时间,就要排除玩家离开游戏之后的时间,而不能直接使用录像的时长。如果要计算APM的话,就必须使用玩家的实际游戏时间来计算。所以在Player.java中加入playTime表示实际游戏时间,通过解析玩家离开游戏的数据块来设置。
Player.java
/**
* 游戏时间
*/
private long playTime;
public long getPlayTime() {
return playTime;
}
public void setPlayTime(long playTime) {
this.playTime = playTime;
}
在UncompressedData类中加入对游戏进行时的信息的解析。
UncompressedData.java
/**
* 游戏进行时的信息
*/
private ReplayData replayData;
public UncompressedData(byte[] uncompressedDataBytes) throws UnsupportedEncodingException, W3GException {
this.uncompressedDataBytes = uncompressedDataBytes;
// 跳过前4个未知字节
offset += 4;
// 解析第一个玩家
analysisPlayerRecode();
// 游戏名称(UTF-8编码)
int begin = offset;
while(uncompressedDataBytes[offset] != 0) {
offset++;
}
gameName = new String(uncompressedDataBytes, begin, offset - begin, "UTF-8");
offset++;
// 跳过一个空字节
offset++;
// 解析一段特殊编码的字节串,其中包含游戏设置、地图和创建者
analysisEncodedBytes();
// 跳过PlayerCount、GameType、LanguageID
offset += 12;
// 解析玩家列表
while(uncompressedDataBytes[offset] == 0x16) {
analysisPlayerRecode();
// 跳过4个未知的字节0x00000000
offset += 4;
}
// GameStartRecord - RecordID、number of data bytes following
offset += 3;
// 解析每个Slot
byte slotCount = uncompressedDataBytes[offset];
offset++;
for(int i = 0; i < slotCount; i++) {
analysisSlotRecode(i);
}
// RandomSeed、RandomSeed、StartSpotCount
offset += 6;
// 游戏进行时的信息解析
replayData = new ReplayData(uncompressedDataBytes, offset, playerList);
}
public ReplayData getReplayData() {
return replayData;
}
修改Test.java类中main方法进行测试。
Test.java
package com.xxg.w3gparser; import java.io.File; import java.io.IOExcepti