Skip to content

Commit

Permalink
Initial beta
Browse files Browse the repository at this point in the history
  • Loading branch information
tso committed Dec 26, 2018
1 parent 2cecc04 commit be83a0d
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 0 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,11 @@
# sc2-auto-scene-switcher
StreamLabs OBS SC2 Auto Scene Switcher

Reason we need proxy: Since the streamlabs plugin is served as js/html we need
to have cross origin requests allowed (specifically
`Access-Control-Allow-Origin="*"`) for our starcraft 2 client api.
Unfortunately I have no control over the starcraft 2 client api, so instead
I've written a proxy which is very simple and adds that header for our client.

TODO:
- Make this less forceful (e.g. only transition to out of game scene if we were _just_ in a game)
74 changes: 74 additions & 0 deletions app/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
const app = new Vue({
el: '#app',
data: {
scenes: [],
sc2InGameScene: '',
sc2OutOfGameScene: '',
sc2ReplayScene: '',
alert: false,
},
methods: {
save: function () {
streamlabs.userSettings.set('in_game_scene', this.sc2InGameScene);
streamlabs.userSettings.set('out_of_game_scene', this.sc2OutOfGameScene);
streamlabs.userSettings.set('replay_scene', this.sc2ReplayScene);
app.alert = true;
setTimeout(() => {
app.alert = false;
}, 2000);
}
}
});


const streamlabs = window.Streamlabs;
const streamlabsOBS = window.streamlabsOBS;
streamlabs.init({ receiveEvents: true })
.then(data => {
console.log('streamlabs initialized');
return streamlabs.userSettings.getAll()
}).then(settings => {
console.log('settings', settings);
app.sc2InGameScene = settings['in_game_scene'];
app.sc2OutOfGameScene = settings['out_of_game_scene'];
app.sc2ReplayScene = settings['replay_scene'];
}).then(() => {
return streamlabsOBS.apiReady
}).then(() => {
console.log('streamlabs obs api ready');
return streamlabsOBS.v1.Scenes.getScenes()
}).then(scenes => {
app.scenes = scenes;
setInterval(() => {
fetch("http://127.0.0.1:6118/ui")
.then(data => { return data.json() })
.then(res => {
if (res['activeScreens'].length) {
streamlabsOBS.v1.Scenes.makeSceneActive(sceneNameToId(scenes, app.sc2OutOfGameScene));
} else {
fetch("http://127.0.0.1:6118/game")
.then(data => { return data.json() })
.then(res => {
if (res['isReplay']) {
streamlabsOBS.v1.Scenes.makeSceneActive(sceneNameToId(scenes, app.sc2ReplayScene));
} else {
streamlabsOBS.v1.Scenes.makeSceneActive(sceneNameToId(scenes, app.sc2InGameScene));
}
});
}
})
.catch(err => {
console.log(err);
});
}, 1500);
})

const sceneNameToId = (scenes, name) => {
for (var scene of scenes) {
if (scene['name'] == name) {
return scene['id'];
}
}

return null;
}
48 changes: 48 additions & 0 deletions app/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="en">
<head>
<title>Starcraft II Auto Scene Switcher</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
<script src="https://cdn.streamlabs.com/slobs-platform/lib/streamlabs-platform.min.js"></script>
<script type="text/javascript" src="vue.js"></script>
<script defer type="text/javascript" src="app.js"></script>
</head>
<body>
<div style="padding-top: 20px" class="container" id="app">
<div v-if="alert" class="alert alert-success" role="alert">Settings saved!</div>
<h2>StarCraft II Auto Scene Switcher</h2>

<form>
<div class="form-group">
<label for="sc2InGameScene">In game scene</label>
<select v-model="sc2InGameScene" class="form-control" id="sc2InGameScene">
<option v-for="scene in scenes">
{{ scene.name }}
</option>
</select>
</div>

<div class="form-group">
<label for="sc2ReplayScene">In replay scene</label>
<select v-model="sc2ReplayScene" class="form-control" id="sc2ReplayScene">
<option v-for="scene in scenes">
{{ scene.name }}
</option>
</select>
</div>

<div class="form-group">
<label for="sc2OutOfGameScene">Out of game scene</label>
<select v-model="sc2OutOfGameScene" class="form-control" id="sc2OutOfGameScene">
<option v-for="scene in scenes">
{{ scene.name }}
</option>
</select>
</div>
<button class="btn btn-primary" v-on:click="save">Save</button>
</form>
</div>
</body>
</html>
16 changes: 16 additions & 0 deletions app/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"version": "0.0.5",
"name": "StarCraft II Auto Scene Switcher",
"permissions": [
"slobs.scenes-sources"
],
"sources": [],
"pages": [
{
"slot": "top_nav",
"file": "index.html",
"allowPopout": false,
"persistent": true
}
]
}
6 changes: 6 additions & 0 deletions app/vue.js

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions proxy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
I'm using go purely because it's easy to write a simple proxy server and
compile to windows from my mac.

I use port 6118 as sc2 uses 6119.

Build using something like `env GOOS=windows GOARCH=386 go build -o sc2_proxy.exe main.go`.
27 changes: 27 additions & 0 deletions proxy/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main

import (
"fmt"
"io/ioutil"
"log"
"net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
resp, err := http.Get(fmt.Sprintf("http://localhost:6119%s", r.URL))
if err != nil {
return
}

defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)

w.Header().Set("Access-Control-Allow-Origin", "*")
fmt.Fprintf(w, string(body))
}

func main() {
http.HandleFunc("/ui", handler)
http.HandleFunc("/game", handler)
log.Fatal(http.ListenAndServe(":6118", nil))
}

0 comments on commit be83a0d

Please sign in to comment.