mirror of
https://github.com/OpenFactorioServerManager/factorio-server-manager.git
synced 2025-01-26 05:27:21 +02:00
added feature to start and stop server, added handlers and ui for starting factorio server
This commit is contained in:
parent
a19dbef3f6
commit
549d214958
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1 @@
|
||||
node_modules/
|
||||
factorio-server-manager
|
||||
|
552
app/bundle.js
552
app/bundle.js
@ -25499,18 +25499,61 @@
|
||||
function App(props) {
|
||||
_classCallCheck(this, App);
|
||||
|
||||
return _possibleConstructorReturn(this, Object.getPrototypeOf(App).call(this, props));
|
||||
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(App).call(this, props));
|
||||
|
||||
_this.facServStatus = _this.facServStatus.bind(_this);
|
||||
_this.getSaves = _this.getSaves.bind(_this);
|
||||
_this.state = {
|
||||
serverRunning: "stopped",
|
||||
saves: []
|
||||
};
|
||||
return _this;
|
||||
}
|
||||
|
||||
_createClass(App, [{
|
||||
key: 'facServStatus',
|
||||
value: function facServStatus() {
|
||||
var _this2 = this;
|
||||
|
||||
$.ajax({
|
||||
url: "/api/server/status",
|
||||
dataType: "json",
|
||||
success: function success(data) {
|
||||
_this2.setState({ serverRunning: data.data.status });
|
||||
}
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'getSaves',
|
||||
value: function getSaves() {
|
||||
var _this3 = this;
|
||||
|
||||
$.ajax({
|
||||
url: "/api/saves/list",
|
||||
dataType: "json",
|
||||
success: function success(data) {
|
||||
_this3.setState({ saves: data.data });
|
||||
},
|
||||
error: function error(xhr, status, err) {
|
||||
console.log('api/mods/list', status, err.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
return _react2.default.createElement(
|
||||
'div',
|
||||
{ className: 'wrapper' },
|
||||
_react2.default.createElement(_Header2.default, null),
|
||||
_react2.default.createElement(_Sidebar2.default, null),
|
||||
_react2.default.cloneElement(this.props.children, { message: "" }),
|
||||
_react2.default.createElement(_Sidebar2.default, {
|
||||
serverStatus: this.facServStatus,
|
||||
serverRunning: this.state.serverRunning
|
||||
}),
|
||||
_react2.default.cloneElement(this.props.children, { message: "",
|
||||
facServerStatus: this.facServStatus,
|
||||
saves: this.state.saves,
|
||||
getSaves: this.getSaves }),
|
||||
_react2.default.createElement(_Footer2.default, null),
|
||||
_react2.default.createElement(_HiddenSidebar2.default, null)
|
||||
);
|
||||
@ -25691,18 +25734,34 @@
|
||||
var Sidebar = function (_React$Component) {
|
||||
_inherits(Sidebar, _React$Component);
|
||||
|
||||
function Sidebar() {
|
||||
function Sidebar(props) {
|
||||
_classCallCheck(this, Sidebar);
|
||||
|
||||
return _possibleConstructorReturn(this, Object.getPrototypeOf(Sidebar).apply(this, arguments));
|
||||
return _possibleConstructorReturn(this, Object.getPrototypeOf(Sidebar).call(this, props));
|
||||
}
|
||||
|
||||
_createClass(Sidebar, [{
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
if (this.props.serverRunning === "running") {
|
||||
var serverStatus = _react2.default.createElement(
|
||||
_reactRouter.IndexLink,
|
||||
{ to: '/' },
|
||||
_react2.default.createElement('i', { className: 'fa fa-circle text-success' }),
|
||||
'Server Online'
|
||||
);
|
||||
} else {
|
||||
var serverStatus = _react2.default.createElement(
|
||||
_reactRouter.IndexLink,
|
||||
{ to: '/' },
|
||||
_react2.default.createElement('i', { className: 'fa fa-circle text-danger' }),
|
||||
'Server Offline'
|
||||
);
|
||||
}
|
||||
|
||||
return _react2.default.createElement(
|
||||
'aside',
|
||||
{ className: 'main-sidebar' },
|
||||
{ className: 'main-sidebar', style: { height: "100%" } },
|
||||
_react2.default.createElement(
|
||||
'section',
|
||||
{ className: 'sidebar' },
|
||||
@ -25722,12 +25781,7 @@
|
||||
null,
|
||||
'Factorio Server Manager'
|
||||
),
|
||||
_react2.default.createElement(
|
||||
'a',
|
||||
{ href: '#' },
|
||||
_react2.default.createElement('i', { className: 'fa fa-circle text-success' }),
|
||||
'Server Online'
|
||||
)
|
||||
serverStatus
|
||||
)
|
||||
),
|
||||
_react2.default.createElement(
|
||||
@ -25756,6 +25810,20 @@
|
||||
{ className: 'header' },
|
||||
'MENU'
|
||||
),
|
||||
_react2.default.createElement(
|
||||
'li',
|
||||
null,
|
||||
_react2.default.createElement(
|
||||
_reactRouter.IndexLink,
|
||||
{ to: '/', activeClassName: 'active' },
|
||||
_react2.default.createElement('i', { className: 'fa fa-link' }),
|
||||
_react2.default.createElement(
|
||||
'span',
|
||||
null,
|
||||
'Server Control'
|
||||
)
|
||||
)
|
||||
),
|
||||
_react2.default.createElement(
|
||||
'li',
|
||||
null,
|
||||
@ -25824,6 +25892,11 @@
|
||||
return Sidebar;
|
||||
}(_react2.default.Component);
|
||||
|
||||
Sidebar.propTypes = {
|
||||
serverStatus: _react2.default.PropTypes.func.isRequired,
|
||||
serverRunning: _react2.default.PropTypes.string.isRequired
|
||||
};
|
||||
|
||||
exports.default = Sidebar;
|
||||
|
||||
/***/ },
|
||||
@ -26907,33 +26980,13 @@
|
||||
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(SavesContent).call(this, props));
|
||||
|
||||
_this.dlSave = _this.dlSave.bind(_this);
|
||||
_this.getSaves = _this.getSaves.bind(_this);
|
||||
_this.state = {
|
||||
saves: []
|
||||
};
|
||||
return _this;
|
||||
}
|
||||
|
||||
_createClass(SavesContent, [{
|
||||
key: 'componentDidMount',
|
||||
value: function componentDidMount() {
|
||||
this.getSaves();
|
||||
}
|
||||
}, {
|
||||
key: 'getSaves',
|
||||
value: function getSaves() {
|
||||
var _this2 = this;
|
||||
|
||||
$.ajax({
|
||||
url: "/api/saves/list",
|
||||
dataType: "json",
|
||||
success: function success(data) {
|
||||
_this2.setState({ saves: data.data });
|
||||
},
|
||||
error: function error(xhr, status, err) {
|
||||
console.log('api/mods/list', status, err.toString());
|
||||
}
|
||||
});
|
||||
this.props.getSaves();
|
||||
}
|
||||
}, {
|
||||
key: 'dlSave',
|
||||
@ -26998,20 +27051,21 @@
|
||||
'div',
|
||||
{ className: 'col-md-6' },
|
||||
_react2.default.createElement(_CreateSave2.default, {
|
||||
getSaves: this.getSaves
|
||||
getSaves: this.props.getSaves
|
||||
})
|
||||
),
|
||||
_react2.default.createElement(
|
||||
'div',
|
||||
{ className: 'col-md-6' },
|
||||
_react2.default.createElement(_UploadSave2.default, {
|
||||
getSaves: this.getSaves
|
||||
getSaves: this.props.getSaves
|
||||
})
|
||||
)
|
||||
),
|
||||
_react2.default.createElement(_SavesList2.default, _extends({}, this.state, {
|
||||
saves: this.props.saves,
|
||||
dlSave: this.dlSave,
|
||||
getSaves: this.getSaves
|
||||
getSaves: this.props.getSaves
|
||||
}))
|
||||
)
|
||||
);
|
||||
@ -27760,6 +27814,110 @@
|
||||
|
||||
/***/ },
|
||||
/* 243 */
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
||||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||
|
||||
var _react = __webpack_require__(1);
|
||||
|
||||
var _react2 = _interopRequireDefault(_react);
|
||||
|
||||
var _ServerCtl = __webpack_require__(244);
|
||||
|
||||
var _ServerCtl2 = _interopRequireDefault(_ServerCtl);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
|
||||
|
||||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||||
|
||||
var Index = function (_React$Component) {
|
||||
_inherits(Index, _React$Component);
|
||||
|
||||
function Index(props) {
|
||||
_classCallCheck(this, Index);
|
||||
|
||||
return _possibleConstructorReturn(this, Object.getPrototypeOf(Index).call(this, props));
|
||||
}
|
||||
|
||||
_createClass(Index, [{
|
||||
key: 'componentDidMount',
|
||||
value: function componentDidMount() {
|
||||
this.props.facServerStatus();
|
||||
this.props.getSaves();
|
||||
}
|
||||
}, {
|
||||
key: 'componentWillUnmount',
|
||||
value: function componentWillUnmount() {
|
||||
this.props.facServerStatus();
|
||||
}
|
||||
}, {
|
||||
key: 'render',
|
||||
value: function render() {
|
||||
return _react2.default.createElement(
|
||||
'div',
|
||||
{ className: 'content-wrapper', style: { height: "100%" } },
|
||||
_react2.default.createElement(
|
||||
'section',
|
||||
{ className: 'content-header' },
|
||||
_react2.default.createElement(
|
||||
'h1',
|
||||
null,
|
||||
'Index',
|
||||
_react2.default.createElement(
|
||||
'small',
|
||||
null,
|
||||
'Optional description'
|
||||
)
|
||||
),
|
||||
_react2.default.createElement(
|
||||
'ol',
|
||||
{ className: 'breadcrumb' },
|
||||
_react2.default.createElement(
|
||||
'li',
|
||||
null,
|
||||
_react2.default.createElement(
|
||||
'a',
|
||||
{ href: '#' },
|
||||
_react2.default.createElement('i', { className: 'fa fa-dashboard' }),
|
||||
' Level'
|
||||
)
|
||||
),
|
||||
_react2.default.createElement(
|
||||
'li',
|
||||
{ className: 'active' },
|
||||
'Here'
|
||||
)
|
||||
)
|
||||
),
|
||||
_react2.default.createElement(
|
||||
'section',
|
||||
{ className: 'content' },
|
||||
_react2.default.createElement(_ServerCtl2.default, {
|
||||
saves: this.props.saves,
|
||||
getSaves: this.props.getSaves
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
}]);
|
||||
|
||||
return Index;
|
||||
}(_react2.default.Component);
|
||||
|
||||
exports.default = Index;
|
||||
|
||||
/***/ },
|
||||
/* 244 */
|
||||
/***/ function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
@ -27782,63 +27940,319 @@
|
||||
|
||||
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
|
||||
|
||||
var Index = function (_React$Component) {
|
||||
_inherits(Index, _React$Component);
|
||||
var ServerCtl = function (_React$Component) {
|
||||
_inherits(ServerCtl, _React$Component);
|
||||
|
||||
function Index() {
|
||||
_classCallCheck(this, Index);
|
||||
function ServerCtl(props) {
|
||||
_classCallCheck(this, ServerCtl);
|
||||
|
||||
return _possibleConstructorReturn(this, Object.getPrototypeOf(Index).apply(this, arguments));
|
||||
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(ServerCtl).call(this, props));
|
||||
|
||||
_this.startServer = _this.startServer.bind(_this);
|
||||
_this.incrementAutosave = _this.incrementAutosave.bind(_this);
|
||||
_this.decrementAutosave = _this.decrementAutosave.bind(_this);
|
||||
|
||||
_this.incrementAutosaveSlots = _this.incrementAutosaveSlots.bind(_this);
|
||||
_this.decrementAutosaveSlots = _this.decrementAutosaveSlots.bind(_this);
|
||||
|
||||
_this.incrementPort = _this.incrementPort.bind(_this);
|
||||
_this.decrementPort = _this.decrementPort.bind(_this);
|
||||
|
||||
_this.incrementLatency = _this.incrementLatency.bind(_this);
|
||||
_this.decrementLatency = _this.decrementLatency.bind(_this);
|
||||
|
||||
_this.toggleAllowCmd = _this.toggleAllowCmd.bind(_this);
|
||||
_this.toggleP2P = _this.toggleP2P.bind(_this);
|
||||
_this.toggleAutoPause = _this.toggleAutoPause.bind(_this);
|
||||
|
||||
_this.state = {
|
||||
latency: 100,
|
||||
autosaveInterval: 5,
|
||||
autosaveSlots: 10,
|
||||
port: 34197,
|
||||
disallowCmd: false,
|
||||
peer2peer: false,
|
||||
autoPause: false
|
||||
};
|
||||
return _this;
|
||||
}
|
||||
|
||||
_createClass(Index, [{
|
||||
_createClass(ServerCtl, [{
|
||||
key: "startServer",
|
||||
value: function startServer(e) {
|
||||
var serverSettings = {
|
||||
latency: Number(this.refs.latency.value),
|
||||
autosave_interval: Number(this.refs.autosaveInterval.value),
|
||||
autosave_slots: Number(this.refs.autosaveSlots.value),
|
||||
port: Number(this.refs.port.value),
|
||||
disallow_cmd: this.refs.allowCmd.checked,
|
||||
peer2peer: this.refs.p2p.checked,
|
||||
auto_pause: this.refs.autoPause.checked
|
||||
};
|
||||
console.log(serverSettings);
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/api/server/start",
|
||||
dataType: "json",
|
||||
data: JSON.stringify(serverSettings),
|
||||
success: function success(resp) {
|
||||
alert(resp);
|
||||
}
|
||||
});
|
||||
e.preventDefault();
|
||||
}
|
||||
}, {
|
||||
key: "incrementAutosave",
|
||||
value: function incrementAutosave() {
|
||||
var saveInterval = this.state.autosaveInterval + 1;
|
||||
this.setState({ autosaveInterval: saveInterval });
|
||||
}
|
||||
}, {
|
||||
key: "decrementAutosave",
|
||||
value: function decrementAutosave() {
|
||||
var saveInterval = this.state.autosaveInterval - 1;
|
||||
this.setState({ autosaveInterval: saveInterval });
|
||||
}
|
||||
}, {
|
||||
key: "incrementAutosaveSlots",
|
||||
value: function incrementAutosaveSlots() {
|
||||
var saveSlots = this.state.autosaveSlots + 1;
|
||||
this.setState({ autosaveSlots: saveSlots });
|
||||
}
|
||||
}, {
|
||||
key: "decrementAutosaveSlots",
|
||||
value: function decrementAutosaveSlots() {
|
||||
var saveSlots = this.state.autosaveSlots - 1;
|
||||
this.setState({ autosaveSlots: saveSlots });
|
||||
}
|
||||
}, {
|
||||
key: "incrementPort",
|
||||
value: function incrementPort() {
|
||||
var port = this.state.port + 1;
|
||||
this.setState({ port: port });
|
||||
}
|
||||
}, {
|
||||
key: "decrementPort",
|
||||
value: function decrementPort() {
|
||||
var port = this.state.port - 1;
|
||||
this.setState({ port: port });
|
||||
}
|
||||
}, {
|
||||
key: "incrementLatency",
|
||||
value: function incrementLatency() {
|
||||
var latency = this.state.latency + 1;
|
||||
this.setState({ latency: latency });
|
||||
}
|
||||
}, {
|
||||
key: "decrementLatency",
|
||||
value: function decrementLatency() {
|
||||
var latency = this.state.latency - 1;
|
||||
this.setState({ latency: latency });
|
||||
}
|
||||
}, {
|
||||
key: "toggleAllowCmd",
|
||||
value: function toggleAllowCmd() {
|
||||
var cmd = !this.state.disallowCmd;
|
||||
this.setState({ disallowCmd: cmd });
|
||||
}
|
||||
}, {
|
||||
key: "toggleP2P",
|
||||
value: function toggleP2P() {
|
||||
var p2p = !this.state.peer2peer;
|
||||
this.setState({ peer2peer: p2p });
|
||||
}
|
||||
}, {
|
||||
key: "toggleAutoPause",
|
||||
value: function toggleAutoPause() {
|
||||
var pause = !this.state.autoPause;
|
||||
this.setState({ autoPause: pause });
|
||||
}
|
||||
}, {
|
||||
key: "render",
|
||||
value: function render() {
|
||||
return _react2.default.createElement(
|
||||
"div",
|
||||
{ className: "content-wrapper" },
|
||||
{ className: "box" },
|
||||
_react2.default.createElement(
|
||||
"section",
|
||||
{ className: "content-header" },
|
||||
"div",
|
||||
{ className: "box-header" },
|
||||
_react2.default.createElement(
|
||||
"h1",
|
||||
null,
|
||||
"Index",
|
||||
_react2.default.createElement(
|
||||
"small",
|
||||
null,
|
||||
"Optional description"
|
||||
)
|
||||
),
|
||||
"h3",
|
||||
{ className: "box-title" },
|
||||
"Server Control"
|
||||
)
|
||||
),
|
||||
_react2.default.createElement(
|
||||
"div",
|
||||
{ className: "box-body" },
|
||||
_react2.default.createElement(
|
||||
"ol",
|
||||
{ className: "breadcrumb" },
|
||||
"form",
|
||||
{ action: "", onSubmit: this.startServer },
|
||||
_react2.default.createElement(
|
||||
"li",
|
||||
null,
|
||||
"label",
|
||||
{ "for": "latency" },
|
||||
"Server latency setting (ms)"
|
||||
),
|
||||
_react2.default.createElement(
|
||||
"div",
|
||||
{ id: "latency", className: "input-group" },
|
||||
_react2.default.createElement("input", { ref: "latency", name: "latency", id: "latency", type: "text", className: "form-control", onchange: this.state.latency, value: this.state.latency, placeholder: this.state.latency }),
|
||||
_react2.default.createElement(
|
||||
"a",
|
||||
{ href: "#" },
|
||||
_react2.default.createElement("i", { className: "fa fa-dashboard" }),
|
||||
" Level"
|
||||
"div",
|
||||
{ className: "input-group-btn" },
|
||||
_react2.default.createElement(
|
||||
"button",
|
||||
{ type: "button", className: "btn btn-primary", onClick: this.incrementLatency },
|
||||
_react2.default.createElement("i", { className: "fa fa-arrow-up" })
|
||||
),
|
||||
_react2.default.createElement(
|
||||
"button",
|
||||
{ type: "button", className: "btn btn-primary", onClick: this.decrementLatency },
|
||||
_react2.default.createElement("i", { className: "fa fa-arrow-down" })
|
||||
)
|
||||
)
|
||||
),
|
||||
_react2.default.createElement(
|
||||
"li",
|
||||
{ className: "active" },
|
||||
"Here"
|
||||
"label",
|
||||
{ "for": "autosaveInterval" },
|
||||
"Autosave Interval (mins)"
|
||||
),
|
||||
_react2.default.createElement(
|
||||
"div",
|
||||
{ id: "autosaveInterval", className: "input-group" },
|
||||
_react2.default.createElement("input", { ref: "autosaveInterval", name: "autosaveInterval", id: "autosaveInterval", type: "text", className: "form-control", onchange: this.state.autosaveInterval, value: this.state.autosaveInterval, placeholder: this.state.autosaveInterval }),
|
||||
_react2.default.createElement(
|
||||
"div",
|
||||
{ className: "input-group-btn" },
|
||||
_react2.default.createElement(
|
||||
"button",
|
||||
{ type: "button", className: "btn btn-primary", onClick: this.incrementAutosave },
|
||||
_react2.default.createElement("i", { className: "fa fa-arrow-up" })
|
||||
),
|
||||
_react2.default.createElement(
|
||||
"button",
|
||||
{ type: "button", className: "btn btn-primary", onClick: this.decrementAutosave },
|
||||
_react2.default.createElement("i", { className: "fa fa-arrow-down" })
|
||||
)
|
||||
)
|
||||
),
|
||||
_react2.default.createElement(
|
||||
"label",
|
||||
{ "for": "autosaveSlots" },
|
||||
"Autosave Slots"
|
||||
),
|
||||
_react2.default.createElement(
|
||||
"div",
|
||||
{ id: "autosaveSlots", className: "input-group" },
|
||||
_react2.default.createElement("input", { ref: "autosaveSlots", name: "autosaveSlots", id: "autosaveSlots", type: "text", className: "form-control", onChange: this.state.autosaveSlots, value: this.state.autosaveSlots, placeholder: this.state.autosaveSlots }),
|
||||
_react2.default.createElement(
|
||||
"div",
|
||||
{ className: "input-group-btn" },
|
||||
_react2.default.createElement(
|
||||
"button",
|
||||
{ type: "button", className: "btn btn-primary", onClick: this.incrementAutosaveSlots },
|
||||
_react2.default.createElement("i", { className: "fa fa-arrow-up" })
|
||||
),
|
||||
_react2.default.createElement(
|
||||
"button",
|
||||
{ type: "button", className: "btn btn-primary", onClick: this.decrementAutosaveSlots },
|
||||
_react2.default.createElement("i", { className: "fa fa-arrow-down" })
|
||||
)
|
||||
)
|
||||
),
|
||||
_react2.default.createElement(
|
||||
"label",
|
||||
{ "for": "port" },
|
||||
"Factorio Server Port"
|
||||
),
|
||||
_react2.default.createElement(
|
||||
"div",
|
||||
{ id: "port", className: "input-group" },
|
||||
_react2.default.createElement("input", { ref: "port", name: "port", id: "port", type: "text", className: "form-control", onChange: this.state.port, value: this.state.port, placeholder: this.state.port }),
|
||||
_react2.default.createElement(
|
||||
"div",
|
||||
{ className: "input-group-btn" },
|
||||
_react2.default.createElement(
|
||||
"button",
|
||||
{ type: "button", className: "btn btn-primary", onClick: this.incrementPort },
|
||||
_react2.default.createElement("i", { className: "fa fa-arrow-up" })
|
||||
),
|
||||
_react2.default.createElement(
|
||||
"button",
|
||||
{ type: "button", className: "btn btn-primary", onClick: this.decrementPort },
|
||||
_react2.default.createElement("i", { className: "fa fa-arrow-down" })
|
||||
)
|
||||
)
|
||||
),
|
||||
_react2.default.createElement(
|
||||
"div",
|
||||
{ "class": "form-group" },
|
||||
_react2.default.createElement(
|
||||
"div",
|
||||
{ "class": "checkbox" },
|
||||
_react2.default.createElement("input", { ref: "autoPause", type: "checkbox", onClick: this.toggleAutoPause }),
|
||||
_react2.default.createElement(
|
||||
"label",
|
||||
null,
|
||||
"Auto Pause when no players connected"
|
||||
)
|
||||
),
|
||||
_react2.default.createElement(
|
||||
"div",
|
||||
{ "class": "checkbox" },
|
||||
_react2.default.createElement("input", { ref: "p2p", type: "checkbox", onClick: this.toggleP2P }),
|
||||
_react2.default.createElement(
|
||||
"label",
|
||||
null,
|
||||
"Peer to peer connection method"
|
||||
)
|
||||
),
|
||||
_react2.default.createElement(
|
||||
"div",
|
||||
{ "class": "checkbox" },
|
||||
_react2.default.createElement("input", { ref: "allowCmd", type: "checkbox", onClick: this.toggleAllowCmd }),
|
||||
_react2.default.createElement(
|
||||
"label",
|
||||
null,
|
||||
"Allow commands on the server"
|
||||
)
|
||||
)
|
||||
),
|
||||
_react2.default.createElement(
|
||||
"div",
|
||||
{ "class": "form-group" },
|
||||
_react2.default.createElement(
|
||||
"select",
|
||||
{ ref: "savefile", "class": "form-control" },
|
||||
this.props.saves.map(function (save, i) {
|
||||
return _react2.default.createElement(
|
||||
"option",
|
||||
{ key: save.name, value: save.name },
|
||||
save.name
|
||||
);
|
||||
})
|
||||
),
|
||||
_react2.default.createElement(
|
||||
"label",
|
||||
null,
|
||||
"Select Save File"
|
||||
)
|
||||
),
|
||||
_react2.default.createElement(
|
||||
"button",
|
||||
{ className: "btn btn-block btn-success", type: "submit" },
|
||||
"Start Factorio Server"
|
||||
)
|
||||
)
|
||||
),
|
||||
_react2.default.createElement("section", { className: "content" })
|
||||
)
|
||||
);
|
||||
}
|
||||
}]);
|
||||
|
||||
return Index;
|
||||
return ServerCtl;
|
||||
}(_react2.default.Component);
|
||||
|
||||
exports.default = Index;
|
||||
exports.default = ServerCtl;
|
||||
|
||||
/***/ }
|
||||
/******/ ]);
|
BIN
factorio-server-manager
Executable file
BIN
factorio-server-manager
Executable file
Binary file not shown.
BIN
factorio-server-manger.exe
Executable file
BIN
factorio-server-manger.exe
Executable file
Binary file not shown.
133
handlers.go
133
handlers.go
@ -4,9 +4,11 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
@ -417,3 +419,134 @@ func LoadConfig(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
log.Printf("Sent config.ini response")
|
||||
}
|
||||
|
||||
func StartServer(w http.ResponseWriter, r *http.Request) {
|
||||
var err error
|
||||
resp := JSONResponse{
|
||||
Success: false,
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
||||
|
||||
if FactorioServ.Running {
|
||||
resp.Data = "Factorio server is already running"
|
||||
if err := json.NewEncoder(w).Encode(resp); err != nil {
|
||||
log.Printf("Error encoding JSON response: ", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
switch r.Method {
|
||||
case "GET":
|
||||
log.Printf("GET not supported for startserver handler")
|
||||
resp.Data = "Unsupported method"
|
||||
resp.Success = false
|
||||
if err = json.NewEncoder(w).Encode(resp); err != nil {
|
||||
log.Printf("Error listing mods: %s", err)
|
||||
}
|
||||
case "POST":
|
||||
log.Printf("Starting Factorio server.")
|
||||
|
||||
// TODO get form parameters for starting server
|
||||
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
log.Printf("Error in starting factorio server handler body: %s", err)
|
||||
return
|
||||
}
|
||||
log.Printf("Starting Factorio server with settings: %v", string(body))
|
||||
|
||||
err = json.Unmarshal(body, &FactorioServ)
|
||||
if err != nil {
|
||||
log.Printf("Error unmarshaling server settings JSON: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
err = FactorioServ.Run()
|
||||
if err != nil {
|
||||
log.Printf("Error starting Factorio server: %s", err)
|
||||
resp.Data = fmt.Sprintf("Error starting Factorio server: %s", err)
|
||||
if err := json.NewEncoder(w).Encode(resp); err != nil {
|
||||
log.Printf("Error encoding config file JSON reponse: ", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
if FactorioServ.Running {
|
||||
log.Printf("Factorio server started on port: %s", FactorioServ.Port)
|
||||
}
|
||||
|
||||
resp.Data = fmt.Sprintf("Factorio server started on port: %s", FactorioServ.Port)
|
||||
resp.Success = true
|
||||
|
||||
if err := json.NewEncoder(w).Encode(resp); err != nil {
|
||||
log.Printf("Error encoding config file JSON reponse: ", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func StopServer(w http.ResponseWriter, r *http.Request) {
|
||||
resp := JSONResponse{
|
||||
Success: false,
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
||||
|
||||
if FactorioServ.Running {
|
||||
err := FactorioServ.Stop()
|
||||
if err != nil {
|
||||
log.Printf("Error in stop server handler: %s", err)
|
||||
resp.Data = fmt.Sprintf("Error in stop server handler: %s", err)
|
||||
if err := json.NewEncoder(w).Encode(resp); err != nil {
|
||||
log.Printf("Error encoding config file JSON reponse: ", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
log.Printf("Stopped Factorio server.")
|
||||
resp.Success = true
|
||||
resp.Data = fmt.Sprintf("Factorio server stopped")
|
||||
} else {
|
||||
resp.Data = "Factorio server is not running"
|
||||
if err := json.NewEncoder(w).Encode(resp); err != nil {
|
||||
log.Printf("Error encoding config file JSON reponse: ", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if err := json.NewEncoder(w).Encode(resp); err != nil {
|
||||
log.Printf("Error encoding config file JSON reponse: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
func RunningServer(w http.ResponseWriter, r *http.Request) {
|
||||
resp := JSONResponse{
|
||||
Success: false,
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
|
||||
|
||||
if FactorioServ.Running {
|
||||
log.Printf("Creating server status response")
|
||||
resp.Success = true
|
||||
status := map[string]string{}
|
||||
status["status"] = "running"
|
||||
status["port"] = strconv.Itoa(FactorioServ.Port)
|
||||
status["savefile"] = FactorioServ.Savefile
|
||||
resp.Data = status
|
||||
if err := json.NewEncoder(w).Encode(resp); err != nil {
|
||||
log.Printf("Error encoding config file JSON reponse: ", err)
|
||||
}
|
||||
log.Printf("Server status sent with data: %+v", resp.Data)
|
||||
} else {
|
||||
log.Printf("Server not running, creating status response")
|
||||
resp.Success = true
|
||||
status := map[string]string{}
|
||||
status["status"] = "stopped"
|
||||
resp.Data = status
|
||||
if err := json.NewEncoder(w).Encode(resp); err != nil {
|
||||
log.Printf("Error encoding config file JSON reponse: ", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
9
main.go
9
main.go
@ -18,7 +18,10 @@ type Config struct {
|
||||
MaxUploadSize int64
|
||||
}
|
||||
|
||||
var config Config
|
||||
var (
|
||||
config Config
|
||||
FactorioServ *FactorioServer
|
||||
)
|
||||
|
||||
func loadFlags() {
|
||||
factorioDir := flag.String("dir", "./", "Specify location of Factorio directory.")
|
||||
@ -44,6 +47,10 @@ func loadFlags() {
|
||||
func main() {
|
||||
loadFlags()
|
||||
|
||||
FactorioServ = initFactorio()
|
||||
FactorioServ.Port = 12345
|
||||
FactorioServ.Savefile = "testingsaves"
|
||||
|
||||
router := NewRouter()
|
||||
|
||||
log.Fatal(http.ListenAndServe(config.ServerIP+":"+config.ServerPort, router))
|
||||
|
22
routes.go
22
routes.go
@ -19,7 +19,7 @@ func NewRouter() *mux.Router {
|
||||
r := mux.NewRouter().StrictSlash(true)
|
||||
|
||||
// API subrouter
|
||||
// Serves all REST handlers prefixed with /api
|
||||
// Serves all JSON REST handlers prefixed with /api
|
||||
s := r.PathPrefix("/api").Subrouter()
|
||||
for _, route := range apiRoutes {
|
||||
s.Methods(route.Method).
|
||||
@ -123,5 +123,25 @@ var apiRoutes = Routes{
|
||||
"GET",
|
||||
"/config",
|
||||
LoadConfig,
|
||||
}, {
|
||||
"StartServer",
|
||||
"GET",
|
||||
"/server/start",
|
||||
StartServer,
|
||||
}, {
|
||||
"StartServer",
|
||||
"POST",
|
||||
"/server/start",
|
||||
StartServer,
|
||||
}, {
|
||||
"StopServer",
|
||||
"GET",
|
||||
"/server/stop",
|
||||
StopServer,
|
||||
}, {
|
||||
"RunningServer",
|
||||
"GET",
|
||||
"/server/status",
|
||||
RunningServer,
|
||||
},
|
||||
}
|
||||
|
104
server.go
104
server.go
@ -1,10 +1,30 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
type FactorioServer struct {
|
||||
Cmd *exec.Cmd
|
||||
Savefile string
|
||||
Latency int `json:"latency"`
|
||||
AutosaveInterval int `json:"autosave_interval"`
|
||||
AutosaveSlots int `json:"autosave_slots"`
|
||||
Port int `json:"port"`
|
||||
DisallowCmd bool `json:"disallow_cmd"`
|
||||
Running bool
|
||||
PeerToPeer bool `json:"peer2peer"`
|
||||
AutoPause bool `json:"auto_pause"`
|
||||
StdOut io.ReadCloser
|
||||
StdErr io.ReadCloser
|
||||
StdIn io.WriteCloser
|
||||
}
|
||||
|
||||
func createSave(saveName string) (string, error) {
|
||||
args := []string{"--create", saveName}
|
||||
|
||||
@ -18,3 +38,87 @@ func createSave(saveName string) (string, error) {
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func initFactorio() *FactorioServer {
|
||||
// TODO move values to config struct
|
||||
f := FactorioServer{
|
||||
Latency: 100,
|
||||
AutosaveInterval: 5,
|
||||
AutosaveSlots: 10,
|
||||
}
|
||||
|
||||
return &f
|
||||
}
|
||||
|
||||
func (f *FactorioServer) Run() error {
|
||||
var err error
|
||||
|
||||
args := []string{"--start-server", f.Savefile,
|
||||
"--latency-ms", strconv.Itoa(f.Latency),
|
||||
"--autosave-interval", strconv.Itoa(f.AutosaveInterval),
|
||||
"--autosave-slots", strconv.Itoa(f.AutosaveSlots),
|
||||
"--port", strconv.Itoa(f.Port)}
|
||||
if f.DisallowCmd {
|
||||
args = append(args, "--disallow-commands")
|
||||
}
|
||||
if f.PeerToPeer {
|
||||
args = append(args, "--peer-to-peer")
|
||||
}
|
||||
if f.AutoPause {
|
||||
args = append(args, "--no-auto-pause")
|
||||
}
|
||||
|
||||
log.Println("Starting server with command: ", config.FactorioBinary, args)
|
||||
|
||||
f.Cmd = exec.Command(config.FactorioBinary, args...)
|
||||
|
||||
f.StdOut, err = f.Cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
log.Printf("Error opening stdout pipe: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
f.StdIn, err = f.Cmd.StdinPipe()
|
||||
if err != nil {
|
||||
log.Printf("Error opening stdin pipe: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
f.StdErr, err = f.Cmd.StderrPipe()
|
||||
if err != nil {
|
||||
log.Printf("Error opening stderr pipe: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
go io.Copy(os.Stdout, f.StdOut)
|
||||
go io.Copy(os.Stderr, f.StdErr)
|
||||
|
||||
err = f.Cmd.Start()
|
||||
if err != nil {
|
||||
log.Printf("Error starting server process: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
f.Running = true
|
||||
|
||||
err = f.Cmd.Wait()
|
||||
if err != nil {
|
||||
log.Printf("Command exited with error: %s", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FactorioServer) Stop() error {
|
||||
err := f.Cmd.Process.Signal(syscall.SIGINT)
|
||||
if err != nil {
|
||||
log.Printf("Error sending SIGINT to Factorio process: %s", err)
|
||||
}
|
||||
|
||||
f.Running = false
|
||||
|
||||
log.Printf("Sent SIGINT to Factorio process")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -8,6 +8,35 @@ import HiddenSidebar from './components/HiddenSidebar.jsx';
|
||||
class App extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.facServStatus = this.facServStatus.bind(this);
|
||||
this.getSaves = this.getSaves.bind(this);
|
||||
this.state = {
|
||||
serverRunning: "stopped",
|
||||
saves: [],
|
||||
}
|
||||
}
|
||||
|
||||
facServStatus() {
|
||||
$.ajax({
|
||||
url: "/api/server/status",
|
||||
dataType: "json",
|
||||
success: (data) => {
|
||||
this.setState({serverRunning: data.data.status})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
getSaves() {
|
||||
$.ajax({
|
||||
url: "/api/saves/list",
|
||||
dataType: "json",
|
||||
success: (data) => {
|
||||
this.setState({saves: data.data})
|
||||
},
|
||||
error: (xhr, status, err) => {
|
||||
console.log('api/mods/list', status, err.toString());
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
@ -16,11 +45,17 @@ class App extends React.Component {
|
||||
|
||||
<Header />
|
||||
|
||||
<Sidebar />
|
||||
<Sidebar
|
||||
serverStatus={this.facServStatus}
|
||||
serverRunning={this.state.serverRunning}
|
||||
/>
|
||||
|
||||
{React.cloneElement(
|
||||
this.props.children,
|
||||
{message: ""}
|
||||
{message: "",
|
||||
facServerStatus: this.facServStatus,
|
||||
saves: this.state.saves,
|
||||
getSaves: this.getSaves}
|
||||
)}
|
||||
|
||||
<Footer />
|
||||
|
@ -1,9 +1,24 @@
|
||||
import React from 'react';
|
||||
import ServerCtl from './ServerCtl/ServerCtl.jsx';
|
||||
|
||||
class Index extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.facServerStatus();
|
||||
this.props.getSaves();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.props.facServerStatus();
|
||||
}
|
||||
|
||||
render() {
|
||||
return(
|
||||
<div className="content-wrapper">
|
||||
<div className="content-wrapper" style={{height: "100%"}}>
|
||||
<section className="content-header">
|
||||
<h1>
|
||||
Index
|
||||
@ -17,6 +32,11 @@ class Index extends React.Component {
|
||||
|
||||
<section className="content">
|
||||
|
||||
<ServerCtl
|
||||
saves={this.props.saves}
|
||||
getSaves={this.props.getSaves}
|
||||
/>
|
||||
|
||||
|
||||
</section>
|
||||
</div>
|
||||
|
@ -7,28 +7,12 @@ class SavesContent extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.dlSave = this.dlSave.bind(this);
|
||||
this.getSaves = this.getSaves.bind(this);
|
||||
this.state = {
|
||||
saves: []
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.getSaves();
|
||||
this.props.getSaves();
|
||||
}
|
||||
|
||||
getSaves() {
|
||||
$.ajax({
|
||||
url: "/api/saves/list",
|
||||
dataType: "json",
|
||||
success: (data) => {
|
||||
this.setState({saves: data.data})
|
||||
},
|
||||
error: (xhr, status, err) => {
|
||||
console.log('api/mods/list', status, err.toString());
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
dlSave(saveName) {
|
||||
$.ajax({
|
||||
@ -61,20 +45,21 @@ class SavesContent extends React.Component {
|
||||
<div className="row">
|
||||
<div className="col-md-6">
|
||||
<CreateSave
|
||||
getSaves={this.getSaves}
|
||||
getSaves={this.props.getSaves}
|
||||
/>
|
||||
</div>
|
||||
<div className="col-md-6">
|
||||
<UploadSave
|
||||
getSaves={this.getSaves}
|
||||
getSaves={this.props.getSaves}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<SavesList
|
||||
{...this.state}
|
||||
saves={this.props.saves}
|
||||
dlSave={this.dlSave}
|
||||
getSaves={this.getSaves}
|
||||
getSaves={this.props.getSaves}
|
||||
/>
|
||||
|
||||
|
||||
|
199
ui/App/components/ServerCtl/ServerCtl.jsx
Normal file
199
ui/App/components/ServerCtl/ServerCtl.jsx
Normal file
@ -0,0 +1,199 @@
|
||||
import React from 'react';
|
||||
|
||||
class ServerCtl extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.startServer = this.startServer.bind(this);
|
||||
this.incrementAutosave = this.incrementAutosave.bind(this);
|
||||
this.decrementAutosave = this.decrementAutosave.bind(this);
|
||||
|
||||
this.incrementAutosaveSlots = this.incrementAutosaveSlots.bind(this);
|
||||
this.decrementAutosaveSlots = this.decrementAutosaveSlots.bind(this);
|
||||
|
||||
this.incrementPort = this.incrementPort.bind(this);
|
||||
this.decrementPort = this.decrementPort.bind(this);
|
||||
|
||||
this.incrementLatency = this.incrementLatency.bind(this);
|
||||
this.decrementLatency = this.decrementLatency.bind(this);
|
||||
|
||||
this.toggleAllowCmd = this.toggleAllowCmd.bind(this);
|
||||
this.toggleP2P = this.toggleP2P.bind(this);
|
||||
this.toggleAutoPause = this.toggleAutoPause.bind(this);
|
||||
|
||||
this.state = {
|
||||
latency: 100,
|
||||
autosaveInterval: 5,
|
||||
autosaveSlots: 10,
|
||||
port: 34197,
|
||||
disallowCmd: false,
|
||||
peer2peer: false,
|
||||
autoPause: false,
|
||||
}
|
||||
}
|
||||
|
||||
startServer(e) {
|
||||
let serverSettings = {
|
||||
latency: Number(this.refs.latency.value),
|
||||
autosave_interval: Number(this.refs.autosaveInterval.value),
|
||||
autosave_slots: Number(this.refs.autosaveSlots.value),
|
||||
port: Number(this.refs.port.value),
|
||||
disallow_cmd: this.refs.allowCmd.checked,
|
||||
peer2peer: this.refs.p2p.checked,
|
||||
auto_pause: this.refs.autoPause.checked,
|
||||
}
|
||||
console.log(serverSettings);
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/api/server/start",
|
||||
dataType: "json",
|
||||
data: JSON.stringify(serverSettings),
|
||||
success: (resp) => {
|
||||
alert(resp)
|
||||
}
|
||||
})
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
incrementAutosave() {
|
||||
let saveInterval = this.state.autosaveInterval + 1;
|
||||
this.setState({autosaveInterval: saveInterval})
|
||||
}
|
||||
|
||||
decrementAutosave() {
|
||||
let saveInterval = this.state.autosaveInterval - 1;
|
||||
this.setState({autosaveInterval: saveInterval})
|
||||
}
|
||||
|
||||
incrementAutosaveSlots() {
|
||||
let saveSlots = this.state.autosaveSlots + 1;
|
||||
this.setState({autosaveSlots: saveSlots})
|
||||
}
|
||||
|
||||
decrementAutosaveSlots() {
|
||||
let saveSlots = this.state.autosaveSlots - 1;
|
||||
this.setState({autosaveSlots: saveSlots})
|
||||
}
|
||||
|
||||
incrementPort() {
|
||||
let port = this.state.port + 1;
|
||||
this.setState({port: port})
|
||||
}
|
||||
|
||||
decrementPort() {
|
||||
let port = this.state.port - 1;
|
||||
this.setState({port: port})
|
||||
}
|
||||
|
||||
incrementLatency() {
|
||||
let latency = this.state.latency + 1;
|
||||
this.setState({latency: latency})
|
||||
}
|
||||
|
||||
decrementLatency() {
|
||||
let latency= this.state.latency- 1;
|
||||
this.setState({latency: latency})
|
||||
}
|
||||
|
||||
toggleAllowCmd() {
|
||||
let cmd = !this.state.disallowCmd
|
||||
this.setState({disallowCmd: cmd})
|
||||
}
|
||||
|
||||
toggleP2P() {
|
||||
let p2p = !this.state.peer2peer;
|
||||
this.setState({peer2peer: p2p})
|
||||
}
|
||||
|
||||
toggleAutoPause() {
|
||||
let pause = !this.state.autoPause;
|
||||
this.setState({autoPause: pause})
|
||||
}
|
||||
|
||||
render() {
|
||||
return(
|
||||
<div className="box">
|
||||
<div className="box-header">
|
||||
<h3 className="box-title">Server Control</h3>
|
||||
</div>
|
||||
|
||||
<div className="box-body">
|
||||
|
||||
<form action="" onSubmit={this.startServer}>
|
||||
<label for="latency">Server latency setting (ms)</label>
|
||||
<div id="latency" className="input-group">
|
||||
<input ref="latency" name="latency" id="latency" type="text" className="form-control" onchange={this.state.latency} value={this.state.latency} placeholder={this.state.latency} />
|
||||
<div className="input-group-btn">
|
||||
<button type="button" className="btn btn-primary" onClick={this.incrementLatency}><i className="fa fa-arrow-up"></i></button>
|
||||
<button type="button" className="btn btn-primary" onClick={this.decrementLatency}><i className="fa fa-arrow-down"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<label for="autosaveInterval">Autosave Interval (mins)</label>
|
||||
<div id="autosaveInterval" className="input-group">
|
||||
<input ref="autosaveInterval" name="autosaveInterval" id="autosaveInterval" type="text" className="form-control" onchange={this.state.autosaveInterval} value={this.state.autosaveInterval} placeholder={this.state.autosaveInterval} />
|
||||
<div className="input-group-btn">
|
||||
<button type="button" className="btn btn-primary" onClick={this.incrementAutosave}><i className="fa fa-arrow-up"></i></button>
|
||||
<button type="button" className="btn btn-primary" onClick={this.decrementAutosave}><i className="fa fa-arrow-down"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<label for="autosaveSlots">Autosave Slots</label>
|
||||
<div id="autosaveSlots" className="input-group">
|
||||
<input ref="autosaveSlots" name="autosaveSlots" id="autosaveSlots" type="text" className="form-control" onChange={this.state.autosaveSlots} value={this.state.autosaveSlots} placeholder={this.state.autosaveSlots} />
|
||||
<div className="input-group-btn">
|
||||
<button type="button" className="btn btn-primary" onClick={this.incrementAutosaveSlots}><i className="fa fa-arrow-up"></i></button>
|
||||
<button type="button" className="btn btn-primary" onClick={this.decrementAutosaveSlots}><i className="fa fa-arrow-down"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<label for="port">Factorio Server Port</label>
|
||||
<div id="port" className="input-group">
|
||||
<input ref="port" name="port" id="port" type="text" className="form-control" onChange={this.state.port} value={this.state.port} placeholder={this.state.port} />
|
||||
<div className="input-group-btn">
|
||||
<button type="button" className="btn btn-primary" onClick={this.incrementPort}><i className="fa fa-arrow-up"></i></button>
|
||||
<button type="button" className="btn btn-primary" onClick={this.decrementPort}><i className="fa fa-arrow-down"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="checkbox">
|
||||
<input ref="autoPause" type="checkbox" onClick={this.toggleAutoPause} />
|
||||
<label>
|
||||
Auto Pause when no players connected
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="checkbox">
|
||||
<input ref="p2p" type="checkbox" onClick={this.toggleP2P} />
|
||||
<label>
|
||||
Peer to peer connection method
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="checkbox">
|
||||
<input ref="allowCmd" type="checkbox" onClick={this.toggleAllowCmd} />
|
||||
<label>
|
||||
Allow commands on the server
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<select ref="savefile" class="form-control">
|
||||
{this.props.saves.map( (save, i) => {
|
||||
return(
|
||||
<option key={save.name} value={save.name}>{save.name}</option>
|
||||
)
|
||||
|
||||
})}
|
||||
</select>
|
||||
<label>Select Save File</label>
|
||||
</div>
|
||||
|
||||
<button className="btn btn-block btn-success" type="submit">Start Factorio Server</button>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default ServerCtl
|
@ -1,10 +1,22 @@
|
||||
import React from 'react';
|
||||
import {Link} from 'react-router';
|
||||
import {Link, IndexLink} from 'react-router';
|
||||
|
||||
class Sidebar extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.props.serverRunning === "running") {
|
||||
var serverStatus =
|
||||
<IndexLink to="/"><i className="fa fa-circle text-success"></i>Server Online</IndexLink>
|
||||
} else {
|
||||
var serverStatus =
|
||||
<IndexLink to="/"><i className="fa fa-circle text-danger"></i>Server Offline</IndexLink>
|
||||
}
|
||||
|
||||
return(
|
||||
<aside className="main-sidebar">
|
||||
<aside className="main-sidebar" style={{height: "100%"}}>
|
||||
|
||||
<section className="sidebar">
|
||||
|
||||
@ -14,7 +26,9 @@ class Sidebar extends React.Component {
|
||||
</div>
|
||||
<div className="pull-left info">
|
||||
<p>Factorio Server Manager</p>
|
||||
<a href="#"><i className="fa fa-circle text-success"></i>Server Online</a>
|
||||
|
||||
{serverStatus}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -30,6 +44,7 @@ class Sidebar extends React.Component {
|
||||
|
||||
<ul className="sidebar-menu">
|
||||
<li className="header">MENU</li>
|
||||
<li><IndexLink to="/" activeClassName="active"><i className="fa fa-link"></i><span>Server Control</span></IndexLink></li>
|
||||
<li><Link to="/mods" activeClassName="active"><i className="fa fa-link"></i><span>Mods</span></Link></li>
|
||||
<li><Link to="/logs" activeClassName="active"><i className="fa fa-link"></i> <span>Logs</span></Link></li>
|
||||
<li><Link to="/saves" activeClassName="active"><i className="fa fa-link"></i> <span>Saves</span></Link></li>
|
||||
@ -41,4 +56,9 @@ class Sidebar extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
Sidebar.propTypes = {
|
||||
serverStatus: React.PropTypes.func.isRequired,
|
||||
serverRunning: React.PropTypes.string.isRequired,
|
||||
}
|
||||
|
||||
export default Sidebar
|
||||
|
Loading…
x
Reference in New Issue
Block a user