Skip to content

Commit

Permalink
Release v2.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
vinnymac committed Jan 6, 2017
2 parents a3b636f + 1d19567 commit cefc848
Show file tree
Hide file tree
Showing 9 changed files with 295 additions and 206 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@

**PokéNurse** is a desktop application for Windows and Mac that allows you to manage your pokémon from Pokémon Go without the need for a mobile device. You can now favorite, transfer, and evolve from the comfort of your own home!

## Downloads for v1.9.0
## Downloads for v2.0.0
You may view all the releases [here](https://github.com/vinnymac/PokeNurse/releases)
* [macOS](https://github.com/vinnymac/PokeNurse/releases/download/v1.9.0/PokeNurse.dmg)
* [Windows](https://github.com/vinnymac/PokeNurse/releases/download/v1.9.0/PokeNurse.exe)
* [Linux 32 bit](https://github.com/vinnymac/PokeNurse/releases/download/v1.9.0/PokeNurse-ia32.deb)
* [Linux 64 bit](https://github.com/vinnymac/PokeNurse/releases/download/v1.9.0/PokeNurse-x64.deb)
* [macOS](https://github.com/vinnymac/PokeNurse/releases/download/v2.0.0/PokeNurse.dmg)
* [Windows](https://github.com/vinnymac/PokeNurse/releases/download/v2.0.0/PokeNurse.exe)
* [Linux 32 bit](https://github.com/vinnymac/PokeNurse/releases/download/v2.0.0/PokeNurse-ia32.deb)
* [Linux 64 bit](https://github.com/vinnymac/PokeNurse/releases/download/v2.0.0/PokeNurse-x64.deb)

## Examples
![Login Window](app/loginExample.png)
Expand Down
29 changes: 18 additions & 11 deletions app/actions/authenticate.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ import {

import * as fs from 'async-file'

import client from '../client'
import { setClient } from '../client'

import {
getTrainerInfo,
getTrainerPokemon
getTrainerInfoAndPokemon,
} from './trainer'

const saveAccountCredentialsFailed = createAction('SAVE_ACCOUNT_CREDENTIALS_FAILED')
Expand All @@ -29,9 +28,7 @@ const userLoginFailed = createAction('USER_LOGIN_FAILED')
const accountPath = path.join(remote.app.getPath('appData'), '/pokenurse/account.json')

export default {
client,

login({ method, username, password }) {
login({ method, username, password, hashingKey }) {
return async (dispatch) => {
dispatch(userLoginStarted())

Expand All @@ -45,15 +42,25 @@ export default {
try {
const token = await login.login(username, password)

client.setAuthInfo(method, token)
const options = {
hashingKey,
authType: method,
authToken: token,
useHashingServer: !!hashingKey,
}

// Use API version 0.51 (minimum version for hashing server)
if (hashingKey) options.version = 5100

const client = new pogobuf.Client(options)

client.init()

setClient(client)

// TODO display a loading spinner
// then fetch all necessary things
await Promise.all([
dispatch(getTrainerInfo()),
dispatch(getTrainerPokemon())
])
await dispatch(getTrainerInfoAndPokemon())

dispatch(userLoginSuccess())
} catch (error) {
Expand Down
110 changes: 69 additions & 41 deletions app/actions/trainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
ipcRenderer,
} from 'electron'

import client from '../client'
import { getClient } from '../client'

// TODO Must move these helpers to app folder
import utils from '../utils'
Expand Down Expand Up @@ -53,7 +53,7 @@ function generateEmptySpecies(candies, pokemonSettings) {
})
}

// TODO Can we find these constants in POGOBuf or item templates?
// TODO Can we find these constants in POGOProtos or item templates?
const MILLISECONDS_FACTOR = 1000
const MOVE2_CHARGE_DELAY_MS = 500
const STAB_MULTIPLIER = 1.25 // 25% damage boost
Expand Down Expand Up @@ -256,18 +256,22 @@ const transferPokemonFailed = createAction('TRANSFER_POKEMON_FAILED')
const evolvePokemonSuccess = createAction('EVOLVE_POKEMON_SUCCESS')
const evolvePokemonFailed = createAction('EVOLVE_POKEMON_FAILED')

function handleGetPlayerResponse(dispatch, response) {
if (!response.success) {
throw new Error('Failed in retrieving player info. Please restart.')
}

dispatch(getTrainerInfoSuccess({
trainerData: response.player_data
}))
}

function getTrainerInfo() {
return async (dispatch) => {
try {
const response = await client.getPlayer()
const response = await getClient().getPlayer()

if (!response.success) {
dispatch(getTrainerInfoFailed('Failed in retrieving player info. Please restart.'))
return
}
dispatch(getTrainerInfoSuccess({
trainerData: response.player_data
}))
handleGetPlayerResponse(dispatch, response)
} catch (error) {
dispatch(getTrainerInfoFailed(error))
}
Expand Down Expand Up @@ -315,9 +319,32 @@ function parseItemTemplates(templates) {

let splitItemTemplates = null

function handleGetItemTemplatesResponse(dispatch, itemTemplates) {
if (!itemTemplates) return

// TODO do not do this everytime we fetch the trainer pokemon, separate first fetch + refresh
itemTemplates.success = itemTemplates.result === 1

if (!itemTemplates.success) {
throw new Error('Failed to retrieve item templates')
}

splitItemTemplates = parseItemTemplates(itemTemplates)
}

function handleGetInventoryResponse(dispatch, inventory) {
if (!inventory.success) {
throw new Error('Failed to retrieve Trainers Pokemon')
}

const payload = parseInventory(inventory)

dispatch(getTrainerPokemonSuccess(payload))
}

async function getInventoryAndItemTemplates(dispatch, inventoryOnly) {
try {
const batch = client.batchStart()
const batch = getClient().batchStart()
batch.getInventory(0)
if (!inventoryOnly) batch.downloadItemTemplates()

Expand All @@ -332,47 +359,47 @@ async function getInventoryAndItemTemplates(dispatch, inventoryOnly) {
[inventory, itemTemplates] = response
}

if (!inventory.success) {
dispatch(getTrainerPokemonFailed('Failed to retrieve Trainers Pokemon'))
return
}

if (!inventoryOnly) {
// TODO do not do this everytime we fetch the trainer pokemon, separate first fetch + refresh
itemTemplates.success = itemTemplates.result === 1

if (!itemTemplates.success) {
dispatch(getTrainerPokemonFailed('Failed to retrieve item templates'))
return
}

splitItemTemplates = parseItemTemplates(itemTemplates)
}

const payload = parseInventory(inventory)

dispatch(getTrainerPokemonSuccess(payload))
handleGetItemTemplatesResponse(dispatch, itemTemplates)
handleGetInventoryResponse(dispatch, inventory)
} catch (error) {
dispatch(getTrainerPokemonFailed(error))
}
}

function getTrainerInfoAndPokemon() {
return async (dispatch) => {
const response = await getClient()
.batchStart()
.getInventory(0)
.downloadItemTemplates()
.getPlayer()
.batchCall()

const [inventory, itemTemplates, player] = response

handleGetItemTemplatesResponse(dispatch, itemTemplates)
handleGetInventoryResponse(dispatch, inventory)
handleGetPlayerResponse(dispatch, player)
}
}

function refreshPokemon() {
return (dispatch) => getInventoryAndItemTemplates(dispatch, true)
return async (dispatch) => getInventoryAndItemTemplates(dispatch, true)
}

// TODO might be unnecessary now
function getTrainerPokemon() {
return (dispatch) => getInventoryAndItemTemplates(dispatch)
return async (dispatch) => getInventoryAndItemTemplates(dispatch)
}

function powerUpPokemon(pokemon) {
return async (dispatch) => {
try {
await client.upgradePokemon(pokemon.id)
await getClient().upgradePokemon(pokemon.id)

// TODO parse the response instead of retrieving all the new pokemon
// Requires replacing the main parsing with more functional code
await dispatch(getTrainerPokemon())
await dispatch(refreshPokemon())
dispatch(powerUpPokemonSuccess(pokemon))
} catch (error) {
dispatch(powerUpPokemonFailed(error))
Expand All @@ -388,7 +415,7 @@ function toggleFavoritePokemon(pokemon) {
favorite: !pokemon.favorite ? -1 : -0
})

await client.setFavoritePokemon(pokemon.id, !!updatedPokemon.favorite)
await getClient().setFavoritePokemon(pokemon.id, !!updatedPokemon.favorite)
dispatch(toggleFavoritePokemonSuccess(updatedPokemon))
} catch (error) {
dispatch(toggleFavoritePokemonFailed(error))
Expand All @@ -401,7 +428,7 @@ function renamePokemon(pokemon, nickname, callback) {

return async (dispatch) => {
try {
await client.nicknamePokemon(updatedPokemon.id, updatedPokemon.nickname)
await getClient().nicknamePokemon(updatedPokemon.id, updatedPokemon.nickname)

dispatch(renamePokemonSuccess(updatedPokemon))

Expand Down Expand Up @@ -429,7 +456,7 @@ function transferPokemon(pokemon, delay) {
return async (dispatch) => {
try {
await sleep(delay)
await client.releasePokemon(pokemon.id)
await getClient().releasePokemon(pokemon.id)
dispatch(transferPokemonSuccess(pokemon))
} catch (error) {
dispatch(transferPokemonFailed(error))
Expand All @@ -442,7 +469,7 @@ function evolvePokemon(pokemon, delay) {
return async (dispatch) => {
try {
await sleep(delay)
await client.evolvePokemon(pokemon.id)
await getClient().evolvePokemon(pokemon.id)
dispatch(evolvePokemonSuccess(pokemon))
} catch (error) {
dispatch(evolvePokemonFailed(error))
Expand All @@ -454,7 +481,7 @@ function evolvePokemon(pokemon, delay) {
const updateMonster = createAction('UPDATE_MONSTER')

function batchStart(selectedPokemon, method) {
let batch = client.batchStart()
let batch = getClient().batchStart()

selectedPokemon.forEach((p) => {
batch = batch[method](p.id)
Expand All @@ -468,7 +495,7 @@ function resetStatusAndGetPokemon(errorMessage) {
try {
dispatch(resetStatus())
await sleep(100) // Pogobuf may need a tick after a large batch
await dispatch(getTrainerPokemon())
await dispatch(refreshPokemon())
if (errorMessage) ipcRenderer.send('error-message', errorMessage)
} catch (e) {
errorMessage = errorMessage ? `${errorMessage}\n\n${e}` : `Failed to fetch pokemon:\n\n${e}`
Expand Down Expand Up @@ -513,6 +540,7 @@ export default {
sortWithDefaults: createAction('SORT_WITH_DEFAULTS'),
getTrainerInfo,
getTrainerPokemon,
getTrainerInfoAndPokemon,
powerUpPokemon,
toggleFavoritePokemon,
renamePokemon,
Expand Down
12 changes: 10 additions & 2 deletions app/client.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
import pogobuf from 'pogobuf'
let client = null

export default new pogobuf.Client()
export default {
getClient() {
return client
},

setClient(c) {
client = c
}
}
6 changes: 3 additions & 3 deletions app/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "PokeNurse",
"productName": "PokeNurse",
"version": "1.9.0",
"version": "2.0.0",
"description": "A tool for Pokémon Go to aid in transferring and evolving Pokémon",
"main": "./main.js",
"author": {
Expand All @@ -13,7 +13,7 @@
"dependencies": {
"async-file": "^2.0.2",
"electron-localshortcut": "^1.0.0",
"node-pogo-protos": "2.4.0",
"pogobuf": "1.8.0"
"node-pogo-protos": "2.4.2",
"pogobuf": "1.9.0"
}
}
Loading

0 comments on commit cefc848

Please sign in to comment.