Skip to content

Commit

Permalink
bg support
Browse files Browse the repository at this point in the history
  • Loading branch information
aza547 committed Aug 14, 2022
1 parent fe87d45 commit 76353ef
Show file tree
Hide file tree
Showing 22 changed files with 17,419 additions and 135 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Resources directory and better test scripts, although they still suck.
- [10](https://github.com/aza547/wow-recorder/issues/10) - Add logging infrastructure.
- Add tray icon and menu. Make minimizing now hide in system tray.
- [33](https://github.com/aza547/wow-recorder/issues/33) - Add tray icon and menu. Make minimizing now hide in system tray.
- [32](https://github.com/aza547/wow-recorder/issues/32) - Add setting to run on start-up.
- [6](https://github.com/aza547/wow-recorder/issues/6) - Battlegrounds is now a supported category.

### Changed
- Record at 60 FPS instead of 30.
Expand Down
Binary file added assets/battlegrounds/AB.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/battlegrounds/AV.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/battlegrounds/BFG.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/battlegrounds/DG.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/battlegrounds/EOTS.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/battlegrounds/IOC.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/battlegrounds/SM.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/battlegrounds/SS.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/battlegrounds/TOK.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/battlegrounds/TP.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/battlegrounds/WSG.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17,085 changes: 17,085 additions & 0 deletions resources/example-logs/rbg.txt

Large diffs are not rendered by default.

35 changes: 35 additions & 0 deletions resources/test-scripts/rbg.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import time
import random

LOG_PATH = "D:/World of Warcraft/_retail_/Logs"
SAMPLE_LOG = "D:/checkouts/wow-recorder/resources/example-logs/rbg.txt"

# Open a combat log ready for writing.
randomNumber = random.random()
logName = f"WoWCombatLog-{randomNumber}.txt"
logFile = open(f"{LOG_PATH}/{logName}", "w", encoding='utf-8')

# Load the sample combat log into memory.
sample_log = open(SAMPLE_LOG, 'r', encoding='utf-8')
sample_log_lines = sample_log.readlines()

# If ARENA_MATCH_START is the first line we don't start recording
# but this never happens in reality so just write a line.
logFile.write("This is a test line to create the file\n")
time.sleep(1)

print("Starting")

# Write each line from the example to the fake log.
for line in sample_log_lines:
if "ZONE_CHANGE" in line:
# Sleep before writing the end event so we actually record something.
time.sleep(5)
logFile.write(line)

print("Done")
logFile.close()




122 changes: 74 additions & 48 deletions src/main/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,49 @@ const months: string[] = [
];

/**
* Zones by ID.
* Battlegrounds by ID.
*/
const zones: { [id: number]: string; } = {
// Arenas (Zone IDs)
1672: "Blade's Edge Arena",
617: "Dalaran Arena",
1505: "Nagrand Arena",
572: "Ruins of Lordaeron",
2167: "The Robodrome",
1134: "Tiger's Peak",
980: "Tol'Viron Arena",
1504: "Black Rook Hold Arena",
2373: "Empyrean Domain",
1552: "Ashamane's Fall",
1911: "Mugambala",
1825: "Hook Point",
2509: "Maldraxxus Coliseum",
2547: "Enigma Crucible",
const battlegrounds: { [id: number]: string; } = {
30: "Alterac Valley",
2107: "Arathi Basin",
1681: "Arathi Basin",
1105: "Deepwind Gorge",
566: "Eye of the Storm",
968: "Eye of the Storm",
628: "Isle of Conquest",
1803: "Seething Shore",
727: "Silvershard Mines",
//607: "Strand of the Ancients",
998: "Temple of Kotmogu",
761: "The Battle for Gilneas",
726: "Twin Peaks",
489: "Warsong Gulch"
}

/**
* Arenas by ID.
*/
const arenas: { [id: number]: string; } = {
1672: "Blade's Edge Arena",
617: "Dalaran Arena",
1505: "Nagrand Arena",
572: "Ruins of Lordaeron",
2167: "The Robodrome",
1134: "Tiger's Peak",
980: "Tol'Viron Arena",
1504: "Black Rook Hold Arena",
2373: "Empyrean Domain",
1552: "Ashamane's Fall",
1911: "Mugambala",
1825: "Hook Point",
2509: "Maldraxxus Coliseum",
2547: "Enigma Crucible",
}

// Raids (Encounter IDs), shortened to fit on button
/**
* Encounters by ID.
*/
const raids: { [id: number]: string; } = {
2537: "Jailer",
2512: "Guardian",
2529: "Halondrus",
Expand All @@ -61,35 +84,35 @@ const zones: { [id: number]: string; } = {
2546: "Anduin",
2549: "Rygelon",
2553: "Xy'mox",
}

/**
* Dungeons by ID.
*/
const dungeons: { [id: number]: string; } = {
2291: "De Other Side",
2287: "Halls of Atonement",
2290: "Mists of Tirna Scithe",
2289: "Plaguefall",
2284: "Sanguine Depths",
2285: "Spires of Ascension",
2286: "The Necrotic Wake",
2293: "Theater of Pain",
2441: "Tazavesh the Veiled Market",
}

// Dungeons (Zone IDs)
2291: "De Other Side",
2287: "Halls of Atonement",
2290: "Mists of Tirna Scithe",
2289: "Plaguefall",
2284: "Sanguine Depths",
2285: "Spires of Ascension",
2286: "The Necrotic Wake",
2293: "Theater of Pain",
2441: "Tazavesh the Veiled Market",

// Battlegrounds (Zone IDs)
30: "Alterac Valley",
2107: "Arathi Basin",
1681: "Arathi Basin",
1105: "Deepwind Gorge",
566: "Eye of the Storm",
968: "Eye of the Storm",
628: "Isle of Conquest",
1803: "Seething Shore",
727: "Silvershard Mines",
607: "Strand of the Ancients",
998: "Temple of Kotmogu",
761: "The Battle for Gilneas",
726: "Twin Peaks",
489: "Warsong Gulch"
/**
* Zones by ID.
*/
const zones: { [id: number]: string; } = {
...arenas,
...raids,
...battlegrounds,
...dungeons,
}



const videoTabsSx = {
position: 'fixed',
bottom: '1px',
Expand Down Expand Up @@ -138,10 +161,13 @@ const videoButtonSx = {
export {
categories,
months,
zones,
videoTabsSx,
categoryTabSx,
categoryTabsSx,
videoButtonSx
};

videoButtonSx,
zones,
arenas,
raids,
battlegrounds,
dungeons
};
84 changes: 71 additions & 13 deletions src/main/logutils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint import/prefer-default-export: off, import/no-mutable-exports: off */
import { startRecording, stopRecording, isRecording, isRecordingCategory} from './main';
import { startRecording, stopRecording, isRecording} from './main';
import { battlegrounds } from './constants';

const tail = require('tail').Tail;
const glob = require('glob');
Expand Down Expand Up @@ -82,7 +83,7 @@ const handleLogLine = (line: string) => {
} else if (line.includes("ENCOUNTER_END")) {
handleRaidStopLine(line);
} else if (line.includes("ZONE_CHANGE")) {
handleZoneChange();
handleZoneChange(line);
} else if (line.includes("COMBATANT_INFO")) {
handleCombatantInfoLine(line);
} else if (line.includes("SPELL_AURA_APPLIED")){
Expand Down Expand Up @@ -171,21 +172,38 @@ const determineArenaMatchResult = (line: string): boolean => {
/**
* Handle a line from the WoW log.
*/
const handleZoneChange = () => {
// No-op if not already recording.
if (!isRecording) return;
const handleZoneChange = (line: string) => {

// Zone change doesn't mean mythic+ is over.
if (isRecordingCategory === "Mythic+") return;
console.log("handling zone cahnge", line);

const videoStopDate = new Date();
const milliSeconds = (videoStopDate.getTime() - videoStartDate.getTime());
metadata.duration = Math.round(milliSeconds / 1000);
const zoneID = parseInt(line.split(',')[1]);
const zoneName = removeQuotes(line.split(',')[2]);

// For some reason two ZONE_CHANGE events seem to fire with the same zoneID.
// so we need to specifically check the ID matches the name.
// 8/14 10:53:06.469 ZONE_CHANGE,998,"Zereth Mortis",0
// 8/14 10:53:06.548 ZONE_CHANGE,998,"Temple of Kotmogu",0
const isBG = (battlegrounds.hasOwnProperty(zoneID)) && (zoneName === battlegrounds[zoneID]);

if (!isRecording && isBG) {
battlegroundStartRecording(line);
} else if (isRecording && isBG) {
battlegroundStopRecording();
} else if (isRecording) {
const videoStopDate = new Date();
const milliSeconds = (videoStopDate.getTime() - videoStartDate.getTime());
metadata.duration = Math.round(milliSeconds / 1000);

// Assume loss if zoned out of content.
metadata.result = false;
stopRecording(metadata);
}

// Assume loss if zoned out of content.
metadata.result = false;
stopRecording(metadata);
if (!isRecording) return;

return;
}

/**
* Handles the SPELL_AURA_APPLIED line from WoW log.
* @param line the SPELL_AURA_APPLIED line
Expand Down Expand Up @@ -217,6 +235,39 @@ const handleCombatantInfoLine = (line: string) => {
combatantInfoMap.set(combatantGUID, combatantData);
}

/**
* ZONE_CHANGE event into a BG.
*/
const battlegroundStartRecording = (line: string) => {
const zoneID = parseInt(line.split(',')[1]);
const battlegroundName = battlegrounds[zoneID];
const category = "Battlegrounds";
videoStartDate = new Date();

metadata = {
name: battlegroundName,
category: category,
zoneID: zoneID,
duration: 0,
result: false,
}

startRecording(metadata);
}

/**
* battlegroundStopRecording
*/
const battlegroundStopRecording = () => {
const videoStopDate = new Date();
const milliSeconds = (videoStopDate.getTime() - videoStartDate.getTime());
metadata.duration = Math.round(milliSeconds / 1000);

// No idea how we can tell who has won a BG so assume loss.
metadata.result = false;
stopRecording(metadata);
}

/**
* Determine if the srcFlags indicate a friendly unit.
* @param srcFlags the srcFlags bitmask
Expand Down Expand Up @@ -247,6 +298,13 @@ const watchLogs = (logdir: any) => {
return true;
}

/**
* Remove double and single quotes from a string.
*/
const removeQuotes = (s: string) => {
return s.replace(/['"]+/g, '');
}

export {
handleLogLine,
watchLogs,
Expand Down
23 changes: 20 additions & 3 deletions src/main/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const obsRecorder = require('./obsRecorder');
/**
* Setup logging. We override console log methods. All console log method will go to
* both the console if it exists, and a file on disk.
* TODO: Currently only main process logs go here. Fix so react component logs go here as well.
*/
const log = require('electron-log');
const date = new Date().toISOString().slice(0, 10);
Expand All @@ -23,6 +24,9 @@ console.log("App starting");

/**
* Create a settings store to handle the config.
* This defaults to a path like:
* - (prod) "C:\Users\alexa\AppData\Roaming\WarcraftRecorder\config.json"
* - (dev) "C:\Users\alexa\AppData\Roaming\Electron\config.json"
*/
const cfg = new Store();
let storageDir: any = cfg.get('storage-path') + "/";
Expand All @@ -32,10 +36,14 @@ let maxStorage: any = cfg.get('max-storage');
/**
* Getter and setter config listeners.
*/
ipcMain.on('cfg-get', async (event, val) => {
event.returnValue = cfg.get(val);
ipcMain.on('cfg-get', async (event, field) => {
const value = cfg.get(field);
console.log("Got from config store: ", field, value);
event.returnValue = value;
});

ipcMain.on('cfg-set', async (_event, key, val) => {
console.log("Setting in config store: ", key, val);
cfg.set(key, val);
});

Expand Down Expand Up @@ -191,7 +199,7 @@ const createSettingsWindow = async () => {
settingsWindow = new BrowserWindow({
show: false,
width: 380,
height: 380,
height: 450,
resizable: true,
icon: getAssetPath('./icon/settings-icon.svg'),
frame: false,
Expand Down Expand Up @@ -306,6 +314,15 @@ ipcMain.on('settingsWindow', (event, args) => {
console.log("User opened settings");
createSettingsWindow();
}

if (args[0] === "startup") {
const isStartUp = (args[1] === "true");
console.log("OS level set start-up behaviour: ", isStartUp);

app.setLoginItemSettings({
openAtLogin: isStartUp
})
}

if (settingsWindow === null) return;

Expand Down
2 changes: 1 addition & 1 deletion src/renderer/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ export default function Layout() {
const generateTabPanel = (tabIndex: number) => {
const haveVideos = state.videoState[category][state.videoIndex];

if (tabIndex === 4 || tabIndex === 6) {
if (tabIndex === 4) {
return unsupportedVideoPanel(tabIndex);
} else if (!haveVideos) {
return noVideoPanel(tabIndex);
Expand Down
Loading

0 comments on commit 76353ef

Please sign in to comment.