add component for console, add routes for websocket message events

This commit is contained in:
majormjr
2016-12-19 22:57:41 -05:00
committed by Mitch Roote
parent 1b196394a6
commit 8aee0e6371
12 changed files with 141 additions and 13 deletions
+49
View File
@@ -10,3 +10,52 @@
position: absolute;
top: 0; left: 0; bottom: 0; right: 0;
}
div.react-console-container {
font-size: 0.85em;
font-family: "Menlo", "Consolas", "DejaVu Sans Mono", monospace;
width: 60em;
max-width: 100%;
box-sizing: border-box;
height: 20em;
background: #efefef;
padding: 0.5em;
overflow: auto;
white-space: pre; }
div.react-console-prompt-box {
color: #444; }
span.react-console-prompt-label {
font-weight: bold; }
div.react-console-focus span.react-console-cursor {
background: #333;
color: #eee; }
div.react-console-nofocus span.react-console-cursor {
background: none;
color: #444;
outline: 0.1em solid #333;
outline-offset: -0.1em; }
div.react-console-focus span.react-console-cursor-idle {
animation: react-console-cursor-animation 1s infinite; }
@keyframes react-console-cursor-animation {
0% {
background: #333;
color: #eee; }
50% {
background: #333;
color: #eee; }
51% {
background: none;
color: #444; }
100% {
background: none;
color: #444; } }
div.react-console-message {
color: #999;
padding: 0.1em; }
+1 -1
View File
@@ -5,5 +5,5 @@
"cookie_encryption_key": "topsecretkey",
"settings_file": "server-settings.json",
"log_file": "factorio-server-manager.log",
"rcon_pass": "factorio_rcon",
"rcon_pass": "factorio_rcon"
}
-3
View File
@@ -40,9 +40,6 @@ func randomPort() int {
func initFactorio() (f *FactorioServer, err error) {
f = new(FactorioServer)
f.Settings = make(map[string]interface{})
config.FactorioRconPort = randomPort()
log.Printf("%v", config)
if err = os.MkdirAll(config.FactorioConfigDir, 0755); err != nil {
return nil, fmt.Errorf("failed to create config directory: %v", err)
+3
View File
@@ -55,6 +55,9 @@ func loadServerConfig(f string) {
decoder := json.NewDecoder(file)
err = decoder.Decode(&config)
failOnError(err, "Error decoding JSON config file.")
config.FactorioRconPort = randomPort()
}
func parseFlags() {
+5
View File
@@ -58,6 +58,7 @@ func NewRouter() *mux.Router {
Methods("GET").
Name("Websocket").
Handler(AuthorizeHandler(ws))
ws.Handle("log subscribe", logSubscribe)
// Serves the frontend application from the app directory
// Uses basic file server to serve index.html and Javascript application
@@ -90,6 +91,10 @@ func NewRouter() *mux.Router {
Methods("GET").
Name("Server").
Handler(AuthorizeHandler(http.StripPrefix("/server", http.FileServer(http.Dir("./app/")))))
r.Path("/console").
Methods("GET").
Name("Server").
Handler(AuthorizeHandler(http.StripPrefix("/console", http.FileServer(http.Dir("./app/")))))
r.PathPrefix("/").
Methods("GET").
Name("Index").
+19
View File
@@ -0,0 +1,19 @@
package main
import (
"log"
"github.com/hpcloud/tail"
)
func logSubscribe(client *Client, data interface{}) {
t, err := tail.TailFile(config.FactorioLog, tail.Config{Follow: true})
if err != nil {
log.Printf("Error subscribing to tail log %s", err)
return
}
for line := range t.Lines {
client.send <- Message{"log update", line.Text}
}
}
+1 -1
View File
@@ -186,7 +186,7 @@ class ConfigContent extends React.Component {
var comment = this.state.serverSettings["_comment_" + key]
return(
<div className="form-group">
<label for={key} className="control-label col-md-3">{setting_key}</label>
<label htmlFor={key} className="control-label col-md-3">{setting_key}</label>
<div className="col-md-6">
{this.formTypeField(key, setting)}
<p className="help-block">{comment}</p>
+53 -2
View File
@@ -1,5 +1,6 @@
import React from 'react';
import {IndexLink} from 'react-router';
import Console from 'react-console-component'
import Socket from '../../socket.js';
class ConsoleContent extends React.Component {
@@ -7,17 +8,67 @@ class ConsoleContent extends React.Component {
super(props);
this.componentDidMount = this.componentDidMount.bind(this);
this.connectWebsocket = this.connectWebsocket.bind(this);
this.handleCommand = this.handleCommand.bind(this);
this.onConnect = this.onConnect.bind(this);
this.onNewLogLine = this.onNewLogLine.bind(this);
this.state = {}
}
componentDidMount() {
this.connectWebsocket()
this.connectWebsocket();
}
connectWebsocket() {
var ws_scheme = window.location.protocol == "https:" ? "wss" : "ws";
let ws = new WebSocket(ws_scheme + "://" + window.location.host + "/ws");
let socket = this.socket = new Socket(ws);
socket.on('connect', this.onConnect.bind(this));
socket.on('log update', this.onNewLogLine.bind(this));
}
handleCommand(command) {
this.refs.console.log(command);
this.refs.console.return();
}
onConnect() {
this.setState({connected: true});
this.socket.emit("log subscribe");
this.refs.console.log("connected to Factorio Server")
}
onNewLogLine(logline) {
console.log(logline);
console.log(this.refs.console);
this.refs.console.log({message: logline});
this.refs.console.return();
}
render() {
return(
<div className="content-wrapper">
<section className="content-header">
<h1>
Server Console
<small>Send commands and messages to the Factorio server</small>
</h1>
<ol className="breadcrumb">
<li><IndexLink to="/"><i className="fa fa-dashboard"></i>Server Control</IndexLink></li>
<li className="active">Here</li>
</ol>
</section>
<section className="content">
<Console ref="console"
autofocus={true}
handler={this.handleCommand}
/>
</section>
</div>
);
}
}
export default ConsoleContent;
+1
View File
@@ -50,6 +50,7 @@ class Sidebar extends React.Component {
<li><Link to="/saves" activeClassName="active"><i className="fa fa-floppy-o"></i> <span>Saves</span></Link></li>
<li><Link to="/config" activeClassName="active"><i className="fa fa-cogs"></i> <span>Game Configuration</span></Link></li>
<li><Link to="/settings" activeClassName="active"><i className="fa fa-cog"></i> <span>Settings</span></Link></li>
<li><Link to="/console" activeClassName="active"><i className="fa fa-terminal"></i> <span>Console</span></Link></li>
</ul>
</section>
<div style={{height: "100%"}}></div>
+1 -1
View File
@@ -61,7 +61,7 @@ class AddUser extends React.Component {
<div className="col-md-4">
<form action="" onSubmit={this.createUser}>
<div className="form-group">
<label for="username">Username</label>
<label htmlFor="username">Username</label>
<input ref="username" type="text" className="form-control" id="username" placeholder="Enter username" />
</div>
<div className="form-group">
+2
View File
@@ -16,12 +16,14 @@
"babel-preset-es2015": "^6.3.13",
"babel-preset-react": "^6.3.13",
"react": "^15.0.1",
"react-console-component": "^0.6.1",
"react-dom": "^15.0.1",
"react-router": "^2.3.0",
"sweetalert": "^1.1.3"
},
"devDependencies": {
"css-loader": "^0.23.1",
"react-console-component": "^0.6.1",
"style-loader": "^0.13.1",
"webpack": "^1.13.0"
}
+6 -5
View File
@@ -1,18 +1,18 @@
import {EventEmitter} from 'events';
class Socket {
constructor(ws = new Websocket(), ee = new EventEmitter()){
constructor(ws = new WebSocket(), ee = new EventEmitter()){
this.ws = ws;
this.ee = ee;
ws.onmessage = this.message.bind(this);
ws.onopen = this.message.bind(this);
ws.onopen = this.open.bind(this);
ws.onclose = this.close.bind(this);
}
on(name, fn){
this.ee.on(name, fn);
}
off(name, fn){
this.ee.RemoveListener(name, fn);
this.ee.removeListener(name, fn);
}
emit(name, data){
const message = JSON.stringify({name, data});
@@ -20,11 +20,12 @@ class Socket {
}
message(e){
try{
const message = JSON.parse(e.data);
let message = JSON.parse(e.data);
console.log(message.name, message.data);
this.ee.emit(message.name, message.data);
}
catch(err){
this.ee.emit('error', err)
this.ee.emit('error', err);
}
}
open(){