added factorio Login to access the mod-portal-API

This commit is contained in:
knoxfighter 2017-07-31 18:45:24 +02:00
parent 2984cc7ceb
commit a97a24dbcd
5 changed files with 190 additions and 34 deletions

View File

@ -50,6 +50,38 @@ func ListInstalledMods(w http.ResponseWriter, r *http.Request) {
}
}
// Login into the Factorio Mod Portal System
func LoginFactorioModPortal(w http.ResponseWriter, r *http.Request) {
var err error
resp := JSONResponse{
Success: false,
}
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
username := r.FormValue("username")
password := r.FormValue("password")
var statusCode int
resp.Data, err, statusCode = getUserToken(username, password)
w.WriteHeader(statusCode)
if err != nil {
resp.Data = fmt.Sprintf("Error in getUserToken or LoginFactorioModPortal handler: %s", err)
if err := json.NewEncoder(w).Encode(resp); err != nil {
log.Printf("Error in Factorio-Login: %s", err)
}
return
}
resp.Success = true
if err := json.NewEncoder(w).Encode(resp); err != nil {
log.Printf("Error in Factorio-Login: %s", err)
}
}
// Toggles mod passed in through mod variable
// Updates mod-list.json file to toggle the enabled status of mods
/*func ToggleMod(w http.ResponseWriter, r *http.Request) {
@ -90,33 +122,8 @@ func ListInstalledMods(w http.ResponseWriter, r *http.Request) {
}
}*/
// Returns JSON response of all mods in the mod-list.json file
/*func ListMods(w http.ResponseWriter, r *http.Request) {
var err error
resp := JSONResponse{
Success: false,
}
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
resp.Data, err = parseModList()
if err != nil {
resp.Data = fmt.Sprintf("Could not parse mod list: %s", err)
if err := json.NewEncoder(w).Encode(resp); err != nil {
log.Printf("Error in list mods: %s", err)
}
return
}
resp.Success = true
if err := json.NewEncoder(w).Encode(resp); err != nil {
log.Printf("Error listing mods: %s", err)
}
}*/
// Uploads mod to the mods directory
func UploadMod(w http.ResponseWriter, r *http.Request) {
/*func UploadMod(w http.ResponseWriter, r *http.Request) {
var err error
resp := JSONResponse{
Success: false,
@ -163,7 +170,7 @@ func UploadMod(w http.ResponseWriter, r *http.Request) {
default:
w.WriteHeader(http.StatusMethodNotAllowed)
}
}
}*/
/*func RemoveMod(w http.ResponseWriter, r *http.Request) {
var err error
@ -195,7 +202,7 @@ func UploadMod(w http.ResponseWriter, r *http.Request) {
}
}*/
func DownloadMod(w http.ResponseWriter, r *http.Request) {
/*func DownloadMod(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
vars := mux.Vars(r)
@ -206,7 +213,7 @@ func DownloadMod(w http.ResponseWriter, r *http.Request) {
log.Printf("%s downloading: %s", r.Host, modFile)
http.ServeFile(w, r, modFile)
}
}*/
/*func CreateModPackHandler(w http.ResponseWriter, r *http.Request) {
var err error
@ -278,7 +285,7 @@ func DownloadMod(w http.ResponseWriter, r *http.Request) {
}
}*/
func DownloadModPack(w http.ResponseWriter, r *http.Request) {
/*func DownloadModPack(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json;charset=UTF-8")
vars := mux.Vars(r)
@ -289,7 +296,7 @@ func DownloadModPack(w http.ResponseWriter, r *http.Request) {
log.Printf("%s downloading: %s", r.Host, modFile)
http.ServeFile(w, r, modFile)
}
}*/
/*func DeleteModPack(w http.ResponseWriter, r *http.Request) {
var err error

View File

@ -4,6 +4,8 @@ import (
"io/ioutil"
"log"
"encoding/json"
"net/http"
"net/url"
)
type Mod struct {
@ -34,3 +36,33 @@ func listInstalledMods(modDir string) ([]Mod, error) {
return result.Mods, nil
}
type LoginErrorResponse struct {
Message string `json:"message"`
Status int `json:"status"`
}
type LoginSuccessResponse struct {
UserKey []string `json:""`
}
//Log the user into factorio, so mods can be downloaded
func getUserToken(username string, password string) (string, error, int) {
resp, get_err := http.PostForm("https://auth.factorio.com/api-login",
url.Values{"require_game_ownership": {"true"}, "username": {username}, "password": {password}})
if get_err != nil {
log.Fatal(get_err)
return "error", get_err, 500
}
text, err_io := ioutil.ReadAll(resp.Body)
resp.Body.Close()
text_string := string(text)
if err_io != nil {
log.Fatal(err_io)
return "error", err_io, resp.StatusCode
}
return text_string, nil, resp.StatusCode
}

View File

@ -153,6 +153,11 @@ var apiRoutes = Routes{
"GET",
"/mods/list/installed",
ListInstalledMods,
}, {
"LoginFactorioModPortal",
"POST",
"/mods/factorio/login",
LoginFactorioModPortal,
}, /*{
"ListMods",
"GET",

View File

@ -1,7 +1,61 @@
import React from 'react';
import Mod from './Mod.jsx';
import ModSearch from './ModSearch.jsx';
class ModOverview extends React.Component {
constructor(props) {
super(props);
this.handlerFactorioLogin = this.handlerFactorioLogin.bind(this);
this.state = {
username: "",
userKey: ""
}
}
handlerSearchMod(e) {
console.log($(e.target).find("input").val());
e.preventDefault();
//TODO
}
handlerFactorioLogin(e) {
e.preventDefault();
let $form = $(e.target);
let username = $form.find('input[name=username]').val();
$.ajax({
// url: "https://auth.factorio.com/api-login",
// url: "https://mods.factorio.com/api/mods",
url: "/api/mods/factorio/login",
method: "POST",
crossDomain: true,
data: $form.serialize(),
dataType: "JSON",
success: (data) => {
swal({
title: "Logged in Successfully",
type: "success"
});
this.setState({
"username": username,
"userKey": (JSON.parse(data.data))[0]
});
},
error: (jqXHR) => {
let json_data = JSON.parse(jqXHR.responseJSON.data);
swal({
title: json_data.message,
type: "error"
});
}
});
}
render() {
return(
<div className="box">
@ -10,18 +64,35 @@ class ModOverview extends React.Component {
</div>
<div className="box-body">
<div className="box box-success collapsed-box">
<button className="btn btn-box-tool" type="button" data-widget="collapse">
<div className="box-header with-border">
<i className="fa fa-plus"></i>
<h4 className="box-title">Add Mods</h4>
</div>
</button>
<div className="box-body">
<ModSearch
{...this.state}
submitSearchMod={this.handlerSearchMod}
submitFactorioLogin={this.handlerFactorioLogin}
/>
</div>
</div>
<div className="table-responsive">
<table className="table table-striped">
<thead>
<tr>
<th>Name</th>
<th>Status</th>
<th>Toggle Status</th>
<th>Toggle/Remove</th>
</tr>
</thead>
<tbody>
{this.props.installedMods.map ( (mod, i) => {
if(mod != "base")
if(mod.name !== "base")
return(
<Mod
key={i}
@ -41,6 +112,6 @@ class ModOverview extends React.Component {
ModOverview.propTypes = {
installedMods: React.PropTypes.array.isRequired
}
};
export default ModOverview;

View File

@ -0,0 +1,41 @@
import React from 'react';
class ModSearch extends React.Component {
render() {
if(this.props.userKey) {
return (
<form onSubmit={this.props.submitSearchMod}>
<div className="input-group col-lg-5">
<input type="text" className="form-control" placeholder="Search for Mod"/>
<span className="input-group-btn">
<input className="btn btn-default" type="submit" value="Go!"/>
</span>
</div>
</form>
)
} else {
return (
<form onSubmit={this.props.submitFactorioLogin}>
<h4>Login into Factorio</h4>
<div className="form-group">
<label htmlFor="factorio-account-name">Factorio Account Name:</label>
<input type="text" className="form-control" id="factorio-account-name" name="username" required />
</div>
<div className="form-group">
<label htmlFor="pwd">Password:</label>
<input type="password" className="form-control" id="pwd" name="password" required />
</div>
<input type="submit" className="btn btn-default" value="Login" />
</form>
)
}
}
}
ModSearch.propTypes = {
submitSearchMod: React.PropTypes.func.isRequired,
userKey: React.PropTypes.string.isRequired,
submitFactorioLogin: React.PropTypes.func.isRequired
}
export default ModSearch;