diff --git a/.gitignore b/.gitignore index 1f1f18e..07f7dd0 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ bot sounds debug youtube +go-discord-bot diff --git a/client/.eslintrc.js b/client/.eslintrc.js deleted file mode 100644 index 15cd681..0000000 --- a/client/.eslintrc.js +++ /dev/null @@ -1,45 +0,0 @@ -module.exports = { - "env": { - "browser": true, - "commonjs": true, - "es6": true, - "node": true - }, - "extends": "eslint:recommended", - "installedESLint": true, - "parserOptions": { - "ecmaFeatures": { - "experimentalObjectRestSpread": true, - "jsx": true - }, - "sourceType": "module" - }, - "plugins": [ - "react" - ], - "rules": { - "indent": [ - "error", - 4 - ], - "semi": [ - "error", - "always" - ], - - "react/display-name": 0, // Prevent missing displayName in a React component definition - "react/jsx-no-undef": 2, // Disallow undeclared variables in JSX - "react/jsx-sort-props": 0, // Enforce props alphabetical sorting - "react/jsx-uses-react": 2, // Prevent React to be incorrectly marked as unused - "react/jsx-uses-vars": 2, // Prevent variables used in JSX to be incorrectly marked as unused - "react/no-did-mount-set-state": 2, // Prevent usage of setState in componentDidMount - "react/no-did-update-set-state": 2, // Prevent usage of setState in componentDidUpdate - "react/no-multi-comp": 0, // Prevent multiple component definition per file - "react/no-unknown-property": 2, // Prevent usage of unknown DOM property - "react/prop-types": 2, // Prevent missing props validation in a React component definition - "react/react-in-jsx-scope": 2, // Prevent missing React when using JSX - "react/self-closing-comp": 2, // Prevent extra closing tags for components without children - "react/wrap-multilines": 2 // Prevent missing parentheses around multilines JSX - } - -}; \ No newline at end of file diff --git a/client/.jsbeautifyrc b/client/.jsbeautifyrc deleted file mode 100644 index c35339e..0000000 --- a/client/.jsbeautifyrc +++ /dev/null @@ -1,15 +0,0 @@ -{ - "indent_size": 4, - "beautify.language": { - "js": { - "type": ["javascript", "json", "jsx"], - "filename": [".jshintrc", ".jsbeautify"], - "e4x": true - // "ext": ["js", "json"] - // ^^ to set extensions to be beautified using the javascript beautifier - }, - "css": ["css", "scss"], - "html": ["htm", "html"] - // ^^ providing just an array sets the VS Code file type - } -} \ No newline at end of file diff --git a/client/app/pages/Pubg/Pubg.scss b/client/app/pages/Pubg/Pubg.scss new file mode 100644 index 0000000..275c12b --- /dev/null +++ b/client/app/pages/Pubg/Pubg.scss @@ -0,0 +1,32 @@ +@import "../../scss/variables"; + +.pubg__container { + padding: 10px; +} + +.pubg__table { + border-collapse: collapse; + width: 100%; + text-align: left; + margin-top: 20px; + + tr + tr { + border-top: 1px solid $gray3; + } + + td, th { + padding: 5px; + } +} + +.pubg__button-row { + margin-bottom: 10px; + + .button { + min-width: 100px; + + & + .button { + margin-left: 5px; + } + } +} diff --git a/client/app/pages/Pubg/Pubg.tsx b/client/app/pages/Pubg/Pubg.tsx index b6fae2b..1bfee08 100644 --- a/client/app/pages/Pubg/Pubg.tsx +++ b/client/app/pages/Pubg/Pubg.tsx @@ -1,10 +1,145 @@ import React from 'react'; +import axios from 'axios'; +import * as _ from 'lodash'; +import './Pubg.scss'; -export class Pubg extends React.Component { +interface Props { + +} + +interface State { + players: Player[]; + selectedRegion: string; + selectedMatch: string; + statList: string[]; +} + +interface Player { + PlayerName: string; + agg?: any; + as?: any; + na?: any; + sa?: any; +} + +export class Pubg extends React.Component { + + constructor() { + super(); + this.state = { + players: [], + selectedRegion: 'agg', + selectedMatch: 'squad', + statList: [], + }; + } + + componentDidMount() { + axios.get("/stats/pubg").then((res) => { + + this.setState({ + players: _.map(res.data) as any, + }); + + this.setStatList(); + }); + } + + // get stat list + setStatList() { + + // hacky way to find existing content -- to tired to make it pretty + let i = 0; + let stats; + while (!stats) { + if (i > this.state.players.length) { + return; + } + + stats = _.find(_.get(this.state, `players[${i}].Stats`), (s: any) => s.Match === this.state.selectedMatch.toLowerCase()); + i++; + } + + if (stats) { + this.setState({ + statList: _.sortBy(_.map(stats.Stats, 'field')) as any, + }); + } + } + + insertRows(): any { + return this.state.statList.map((val: any, index: any) => { + return ( + + {val} + {this.state.players.map((player: any, i: number) => { + // find player stats for field + let playerStat = _.find(player.Stats, (p: any) => { + return p.Match === this.state.selectedMatch.toLowerCase() && p.Region === this.state.selectedRegion.toLowerCase(); + }); + + return {_.get(_.find(_.get(playerStat, 'Stats'), (p: any) => p.field === val), 'displayValue')} + })} + + ); + }); + } + + buttonRegion(title: string) { + let lowerTitle = title === 'All' ? 'agg' : title.toLowerCase() + return ( + + ); + } + + buttonMatch(title: string) { + let lowerTitle = title.toLowerCase() + return ( + + ); + } render() { return ( -
test 123
+
+
+
PUBG Stats
+ +
+ {this.buttonMatch('Solo')} + {this.buttonMatch('Duo')} + {this.buttonMatch('Squad')} +
+ +
+ {this.buttonRegion('All')} + {this.buttonRegion('Na')} + {this.buttonRegion('As')} + {this.buttonRegion('Au')} +
+ + + + + + {this.state.players.map((val: any, index: number) => { + return ; + })} + + {this.insertRows()} + +
{val.PlayerName}
+ +
+
); } } diff --git a/client/package.json b/client/package.json index fece963..7e2fdab 100644 --- a/client/package.json +++ b/client/package.json @@ -10,6 +10,7 @@ "author": "Mitchell Gerber", "license": "MIT", "devDependencies": { + "@types/lodash": "^4.14.71", "@types/react": "^16.0.0", "@types/react-dom": "^15.5.1", "@types/react-dropzone": "^3.13.1", @@ -29,6 +30,7 @@ "extract-text-webpack-plugin": "2.0.0-rc.1", "file-loader": "^0.10.0", "html-webpack-plugin": "^2.24.1", + "lodash": "^4.17.4", "node-sass": "^4.5.3", "postcss-loader": "^1.2.1", "react": "15.6.1", diff --git a/client/yarn.lock b/client/yarn.lock index b99317c..6b53943 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -6,6 +6,10 @@ version "3.2.1" resolved "https://registry.yarnpkg.com/@types/history/-/history-3.2.1.tgz#0039ab0e0be2a0cc22bac171d27a44588103d123" +"@types/lodash@^4.14.71": + version "4.14.71" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.71.tgz#0dc383f78981216ac76e2f2c3afd998e0450e4c1" + "@types/react-dom@^15.5.1": version "15.5.1" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-15.5.1.tgz#f3c3e14c682785923c7d64583537df319442dec1" @@ -2955,7 +2959,7 @@ lodash.uniq@^4.3.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" -lodash@^4.0.0, lodash@^4.14.0, lodash@^4.17.2, lodash@^4.17.3, lodash@^4.2.0, lodash@^4.3.0: +lodash@^4.0.0, lodash@^4.14.0, lodash@^4.17.2, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.3.0: version "4.17.4" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" diff --git a/config.template.json b/config.template.json index 9c5d374..7daa397 100644 --- a/config.template.json +++ b/config.template.json @@ -3,5 +3,10 @@ "BotPrefix": "#", "SoundsPath": "./sounds/", "UploadPassword": "", - "ServerAddr": ":80" + "ServerAddr": ":80", + "pubg": { + "apiKey": "", + "enabled": true, + "players": ["player1"] + } } diff --git a/main.go b/main.go index 420a04a..4fa1d76 100644 --- a/main.go +++ b/main.go @@ -16,11 +16,9 @@ func main() { //add handlers bot.AddHandler(bothandlers.SoundsHandler) - // remove gif functionality for not - //bot.AddHandler(bothandlers.GifHandler) - // start new go routine for the discord websockets - go bot.Start() + // start the bot + bot.Start() // start the web server webserver.Start() diff --git a/server/bot/bot.go b/server/bot/bot.go index 6c85709..5da0675 100644 --- a/server/bot/bot.go +++ b/server/bot/bot.go @@ -39,18 +39,22 @@ func Connect(token string) { // Start - blocking function that starts a websocket listenting for discord callbacks func Start() { - // Open the websocket and begin listening. - err := Session.Open() - if err != nil { - fmt.Println("error opening connection,", err) + + // start new non blocking go routine + go func() { + // Open the websocket and begin listening. + err := Session.Open() + if err != nil { + fmt.Println("error opening connection,", err) + return + } + + fmt.Println("Bot is now running...") + + // Simple way to keep program running until CTRL-C is pressed. + <-make(chan struct{}) return - } - - fmt.Println("Bot is now running...") - - // Simple way to keep program running until CTRL-C is pressed. - <-make(chan struct{}) - return + }() } func AddHandler(handler interface{}) { diff --git a/server/config/config.go b/server/config/config.go index c291484..5a1169c 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -20,6 +20,11 @@ type configFile struct { SoundsPath string `json:"SoundsPath"` UploadPassword string `json:"UploadPassword"` ServerAddr string `json:"ServerAddr` + Pubg struct { + Enabled bool `json:"enabled"` + APIKey string `json:"apiKey"` + Players []string `json:"players"` + } `json:"pubg"` } type configFlags struct { diff --git a/server/webserver/pubg/pubg.go b/server/webserver/pubg/pubg.go new file mode 100644 index 0000000..5574dfc --- /dev/null +++ b/server/webserver/pubg/pubg.go @@ -0,0 +1,54 @@ +package pubg + +import ( + "log" + "net/http" + "sync" + "time" + + "github.com/mgerb/chi_auth_server/response" + pubgClient "github.com/mgerb/go-pubg" +) + +var ( + apiKey string + stats = map[string]*pubgClient.Player{} + mut = &sync.Mutex{} +) + +// Start - +func Start(key string, players []string) { + + apiKey = key + + log.Println("Gathering pubg data...") + + go fetchStats(players) +} + +func fetchStats(players []string) { + + api := pubgClient.New(apiKey) + + // fetch new stats every 30 seconds + for { + + for _, player := range players { + newStats := api.GetPlayer(player) + + mut.Lock() + stats[player] = newStats + mut.Unlock() + + time.Sleep(time.Second * 2) + } + + time.Sleep(time.Second * 30) + } + +} + +// Handler - returns the pubg stats +func Handler(w http.ResponseWriter, r *http.Request) { + response.JSON(w, stats) +} diff --git a/server/webserver/server.go b/server/webserver/server.go index 0b34ee1..f34e566 100644 --- a/server/webserver/server.go +++ b/server/webserver/server.go @@ -13,6 +13,7 @@ import ( "github.com/go-chi/chi/middleware" "github.com/mgerb/go-discord-bot/server/config" "github.com/mgerb/go-discord-bot/server/webserver/handlers" + "github.com/mgerb/go-discord-bot/server/webserver/pubg" ) func getRouter() *chi.Mux { @@ -40,12 +41,19 @@ func getRouter() *chi.Mux { r.Get("/soundlist", handlers.SoundList) r.Put("/upload", handlers.FileUpload) r.Get("/ytdownloader", handlers.Downloader) + r.Get("/stats/pubg", pubg.Handler) return r } // Start - func Start() { + + // start gathering pubg data from the api + if config.Config.Pubg.Enabled { + pubg.Start(config.Config.Pubg.APIKey, config.Config.Pubg.Players) + } + router := getRouter() if config.Flags.TLS {