public static Dictionary <string, string> split_config_game(string src) { var split = new ListMap <string, string>(Q3Utils.split_config(src)); Dictionary <string, string> replaces = new Dictionary <string, string>(); replaces.Add("defrag_clfps", "com_maxfps"); replaces.Add("defrag_svfps", "sv_fps"); replaceKeys(split, replaces); return(split.ToDictionary()); }
public static Dictionary <string, string> split_config_player(string src) { var split = new ListMap <string, string>(Q3Utils.split_config(src)); Dictionary <string, string> replaces = new Dictionary <string, string>(); replaces.Add("n", "name"); replaces.Add("dfn", "df_name"); replaces.Add("t", "team"); replaces.Add("c1", "color1"); replaces.Add("c2", "color2"); replaces.Add("hc", "maxHealth"); replaces.Add("w", "wins"); replaces.Add("l", "losses"); replaces.Add("tt", "teamTask"); replaces.Add("tl", "teamLeader"); replaceKeys(split, replaces); var nameIndex = Ext.IndexOf(split, x => x.Key.ToLowerInvariant() == "name"); if (nameIndex >= 0) { var name = split[nameIndex].Value; string unColoredName = removeColors(name); if (!name.Equals(unColoredName)) { split.Insert(nameIndex + 1, new KeyValuePair <string, string>("uncoloredName", unColoredName)); } } Dictionary <string, string> res = split.ToDictionary(); if (res.ContainsKey("team")) { int teamvalue; int.TryParse(res["team"], out teamvalue); if (teamvalue >= 0 && teamvalue < teamsFrendlyInfo.Length) { res["team"] = teamsFrendlyInfo[teamvalue]; } } return(res); }
public static Dictionary <string, Dictionary <string, string> > getFriendlyConfig(string file_name) { Dictionary <short, string> conf = getRawConfigStrings(file_name); if (conf == null) { return(null); } Dictionary <string, Dictionary <string, string> > result = new Dictionary <string, Dictionary <string, string> >(); if (conf[Q3Const.Q3_DEMO_CFG_FIELD_CLIENT] != null) { result["client"] = Q3Utils.split_config(conf[Q3Const.Q3_DEMO_CFG_FIELD_CLIENT]); //result["client_version"] = result["client"]["version"]; //result["physic"] = result['client']['df_promode'] == 0 ? 'vq3' : 'cpm'; } if (conf[Q3Const.Q3_DEMO_CFG_FIELD_GAME] != null) { result["game"] = Q3Utils.split_config(conf[Q3Const.Q3_DEMO_CFG_FIELD_GAME]); } if (conf[Q3Const.Q3_DEMO_CFG_FIELD_PLAYER] != null) { result["player"] = Q3Utils.split_config(conf[Q3Const.Q3_DEMO_CFG_FIELD_PLAYER]); } Dictionary <string, string> raw = new Dictionary <string, string>(); foreach (var r in conf) { raw.Add(r.Key.ToString(), r.Value); } result["raw"] = raw; return(result); }
public Dictionary <string, Dictionary <string, string> > getFriendlyInfo() { if (friendlyInfo != null) { return(friendlyInfo); } //All players var keyP = Q3Const.Q3_DEMO_CFG_FIELD_PLAYER; for (short i = 0; i < 32; i++) { var k1 = (short)(keyP + i); if (rawConfig.ContainsKey(k1)) { allPlayersConfigs.Add(k1, split_config_player(rawConfig[k1])); } } //Current player if (fin.HasValue) { kPlayer = getPlayerInfoByPlayerNum(fin.Value.Value.playerNum); } if (kPlayer == null && clientEvents.Count > 0) { //if spectator view player and there was no finish var lastEvent = clientEvents.LastOrDefault(); if (lastEvent != null) { kPlayer = getPlayerInfoByPlayerNum(lastEvent.playerNum); } } if (kPlayer == null) { kPlayer = getPlayerInfoByPlayerNum(clc.clientNum); } var keys = allPlayersConfigs.Keys.ToList(); if (kPlayer == null && keys.Count == 1) { kPlayer = allPlayersConfigs[keys[0]]; } friendlyInfo = new Dictionary <string, Dictionary <string, string> >(); //console Times Dictionary <string, string> times = new Dictionary <string, string>(); times.Add(keyDemoName, new FileInfo(demoPath).Name); if (timeStrings.Count > 0) { var strInfo = GetGoodTimeStringInfo(); if (strInfo != null) { if (!string.IsNullOrEmpty(strInfo.recordDateString)) { times.Add(keyRecordDate, strInfo.recordDateString); } times.Add(keyRecordTime, strInfo.timeString); } else { for (int i = 0; i < timeStrings.Count; i++) { var timeInfo = timeStrings[i]; if (!string.IsNullOrEmpty(timeInfo.recordDateString)) { string keyDate = timeStrings.Count > 1 ? keyRecordDate + " " + (i + 1) : keyRecordDate; times.Add(keyDate, timeInfo.recordDateString); } string keyTime = timeStrings.Count > 1 ? keyRecordTime + " " + (i + 1) : keyRecordTime; times.Add(keyTime, timeInfo.timeString); } } } if (fin != null) { string bestTime = getTimeByMillis(fin.Value.Value.time); bool hasTr = fin.Value.Key > 1; string trAdd = hasTr ? " (Time reset)" : ""; times.Add(keyBestTime, bestTime + trAdd); } friendlyInfo.Add(keyRecord, times); //demo triggers if (clientEvents != null && clientEvents.Count > 0) { Dictionary <string, string> triggers = new Dictionary <string, string>(); try { int stCount = 0; int trCount = 0; int cpCount = 0; int ftCount = 0; int pmCount = 0; int cuCount = 0; int tCount = 0; for (int i = 0; i < clientEvents.Count; i++) { ClientEvent ce = clientEvents[i]; string diff = ""; if (i > 0) { var prev = clientEvents[i - 1]; long t = ce.serverTime - prev.serverTime; if (t > 0 && prev.serverTime > 0) { diff = string.Format(" (+{0})", getDiffByMillis(t)); } } if (ce.eventStartFile) { var user = getPlayerInfoByPlayerNum(clc.clientNum); if (user == null) { user = getPlayerInfoByPlayerNum(ce.playerNum); } string username = user == null ? null : Ext.GetOrNull(user, "name"); string userString = string.IsNullOrEmpty(username) ? "" : "Client: " + username; triggers.Add("StartFile", userString); } if (ce.eventStartTime) { var user = getPlayerInfoByPlayerNum(ce.playerNum); string username = user == null ? null : Ext.GetOrNull(user, "name"); string userString = string.IsNullOrEmpty(username) ? "" : "Player: " + username; triggers.Add("StartTimer" + getNumKey(++stCount), userString + diff); } if (ce.eventTimeReset) { var user = getPlayerInfoByPlayerNum(ce.playerNum); string username = user == null ? null : Ext.GetOrNull(user, "name"); string userString = string.IsNullOrEmpty(username) ? "" : "Player: " + username; triggers.Add("TimeReset" + getNumKey(++trCount), userString + diff); } if (ce.eventFinish) { triggers.Add("FinishTimer" + getNumKey(++ftCount), getTimeByMillis(ce.time) + diff); } if (ce.eventCheckPoint) { triggers.Add("CheckPoint" + getNumKey(++cpCount), getTimeByMillis(ce.time) + diff); } if (ce.eventChangePmType) { string pmString = ce.playerMode < ClientEvent.pmTypesStrings.Length ? ClientEvent.pmTypesStrings[ce.playerMode] : ce.playerMode.ToString(); triggers.Add("ChangePlayerMode" + getNumKey(++pmCount), pmString + diff); } if (ce.eventSomeTrigger && ce.playerMode == (int)ClientEvent.PlayerMode.PM_NORMAL) { triggers.Add("EventTrigger" + getNumKey(++tCount), getTimeByMillis(ce.time) + diff); } if (ce.eventChangeUser) { var user = getPlayerInfoByPlayerNum(ce.playerNum); string username = user == null ? null : Ext.GetOrNull(user, "name"); string userString = string.IsNullOrEmpty(username) ? "" : "Player: " + username; triggers.Add("ChangeUser" + getNumKey(++cuCount), userString + diff); } } } catch (Exception ex) { Q3Utils.PrintDebug(clc.errors, ex.Message); } friendlyInfo.Add(keyTriggers, triggers); } if (rawConfig == null) { return(friendlyInfo); } //Player if (kPlayer != null) { friendlyInfo.Add(keyPlayer, kPlayer); } else { for (int i = 0; i < keys.Count; i++) { friendlyInfo.Add(keyPlayer + " " + (i + 1).ToString(), allPlayersConfigs[keys[i]]); } } Dictionary <string, string> clInfo = null; Dictionary <string, string> gInfo = null; if (rawConfig.ContainsKey(Q3Const.Q3_DEMO_CFG_FIELD_CLIENT)) { clInfo = Q3Utils.split_config(rawConfig[Q3Const.Q3_DEMO_CFG_FIELD_CLIENT]); } if (rawConfig.ContainsKey(Q3Const.Q3_DEMO_CFG_FIELD_GAME)) { gInfo = split_config_game(rawConfig[Q3Const.Q3_DEMO_CFG_FIELD_GAME]); } //Gametype var parameters = Ext.Join(clInfo, gInfo); gameInfo = new GameInfo(parameters); var gameInfoDict = new Dictionary <string, string>(); if (parameters.Count > 0) { bool diff = gameInfo.gameName.ToLowerInvariant() != gameInfo.gameNameShort.ToLowerInvariant(); if (diff) { gameInfoDict.Add("gameName", string.Format("{0} ({1})", gameInfo.gameName, gameInfo.gameNameShort)); } else { gameInfoDict.Add("gameName", gameInfo.gameName); } gameInfoDict.Add("gameType", string.Format("{0} ({1})", gameInfo.gameType, gameInfo.gameTypeShort)); if (!string.IsNullOrEmpty(gameInfo.gameplayTypeShort)) { gameInfoDict.Add("gameplay", string.Format("{0} ({1})", gameInfo.gameplayType, gameInfo.gameplayTypeShort)); } if (!string.IsNullOrEmpty(gameInfo.modType)) { gameInfoDict.Add("modType", string.Format("{0} ({1})", gameInfo.modTypeName, gameInfo.modType)); } } //Game var game = Ext.Join(gameInfoDict, gInfo); if (game.Count > 0) { friendlyInfo.Add(keyGame, game); } //Client if (clInfo != null) { friendlyInfo.Add(keyClient, clInfo); } //Raw configs Dictionary <string, string> raw = new Dictionary <string, string>(); foreach (var r in rawConfig) { raw.Add(r.Key.ToString(), r.Value); } friendlyInfo.Add(keyRaw, raw); //Console commands if (clc.console.Count > 0) { Dictionary <string, string> conTexts = new Dictionary <string, string>(); foreach (var kv in clc.console) { conTexts.Add(kv.Key.ToString(), removeColors(kv.Value.ToString())); } friendlyInfo.Add(keyConsole, conTexts); } if (clc.errors.Count > 0) { Dictionary <string, string> errTexts = new Dictionary <string, string>(); int i = 0; foreach (var kv in clc.errors) { errTexts.Add((++i).ToString(), kv.Key.ToString()); } friendlyInfo.Add(keyErrors, errTexts); } return(friendlyInfo); }
private void parseSnapshot(Q3HuffmanReader decoder) { if (client.clientConfig == null) { client.clientConfig = new Dictionary <string, string>(); if (clc.configs.ContainsKey(Q3Const.Q3_DEMO_CFG_FIELD_GAME)) { var gameConfig = Q3Utils.split_config(clc.configs[Q3Const.Q3_DEMO_CFG_FIELD_GAME]); client.isCheatsOn = Ext.GetOrZero(gameConfig, "sv_cheats") > 0; } if (clc.configs.ContainsKey(Q3Const.Q3_DEMO_CFG_FIELD_CLIENT)) { client.clientConfig = Q3Utils.split_config(clc.configs[Q3Const.Q3_DEMO_CFG_FIELD_CLIENT]); client.dfvers = Ext.GetOrZero(client.clientConfig, "defrag_vers"); client.mapname = Ext.GetOrNull(client.clientConfig, "mapname"); client.mapNameChecksum = getMapNameChecksum(client.mapname); client.isOnline = Ext.GetOrZero(client.clientConfig, "defrag_gametype") > 4; } } CLSnapshot newSnap = new CLSnapshot(); CLSnapshot old = null; newSnap.serverCommandNum = clc.serverCommandSequence; newSnap.serverTime = decoder.readLong(); newSnap.messageNum = clc.serverMessageSequence; int deltaNum = decoder.readByte(); if (deltaNum == 0) { newSnap.deltaNum = -1; } else { newSnap.deltaNum = newSnap.messageNum - deltaNum; } newSnap.snapFlags = decoder.readByte(); // If the frame is delta compressed from data that we // no longer have available, we must suck up the rest of // the frame, but not use it, then ask for a non-compressed // message if (newSnap.deltaNum <= 0) { newSnap.valid = true; // uncompressed frame old = null; clc.demowaiting = false; // we can start recording now } else { old = Ext2 <int, CLSnapshot> .GetOrCreate(client.snapshots, newSnap.deltaNum& Q3Const.PACKET_MASK); if (old == null || !old.valid) { // should never happen Q3Utils.PrintDebug(clc.errors, "Delta from invalid frame (not supposed to happen!)"); } else if (old.messageNum != newSnap.deltaNum) { // The frame that the server did the delta from // is too old, so we can't reconstruct it properly. Q3Utils.PrintDebug(clc.errors, "Delta frame too old."); } else if ((client.parseEntitiesNum - old.parseEntitiesNum) > (Q3Const.MAX_PARSE_ENTITIES - 128)) { Q3Utils.PrintDebug(clc.errors, "Delta parseEntitiesNum too old"); } else { newSnap.valid = true; // valid delta parse } } int len = decoder.readByte(); if (len > newSnap.areamask.Length) { Q3Utils.PrintDebug(clc.errors, "CL_ParseSnapshot: Invalid size {0} for areamask", len); return; } decoder.readData(newSnap.areamask, len); if (old != null) { newSnap.ps.copy(old.ps); } decoder.readDeltaPlayerState(newSnap.ps); parsePacketEntities(decoder, old, newSnap); // if not valid, dump the entire thing now that it has // been properly read if (!newSnap.valid) { return; } // clear the valid flags of any snapshots between the last // received and this one, so if there was a dropped packet // it won't look like something valid to delta from next // time we wrap around in the buffer int oldMessageNum = client.snap.messageNum + 1; if (newSnap.messageNum - oldMessageNum >= Q3Const.PACKET_BACKUP) { oldMessageNum = newSnap.messageNum - (Q3Const.PACKET_BACKUP - 1); } for (; oldMessageNum < newSnap.messageNum; oldMessageNum++) { CLSnapshot s; if (client.snapshots.TryGetValue(oldMessageNum & Q3Const.PACKET_MASK, out s)) { if (s != null) { s.valid = false; } } } // copy to the current good spot client.snap = newSnap; // skip ping calculations client.snap.ping = 0; // save the frame off in the backup array for later delta comparisons client.snapshots[client.snap.messageNum & Q3Const.PACKET_MASK] = client.snap; client.newSnapshots = true; updateClientEvents(newSnap); }