Transferring Interger once a game has started GameKit - game-center

I have successfully used the Apple Documentation to connect two players via Game Center and start the game. However, I have been struggling for days at getting the app to send data between two players.
I just need to send an integer between the two players but can't even get the documentation code to run, even after creating the structs etc. Examples I have looked at already are dated or I can't get them to build.
func sendPosition() {
let messageToSend = 123
//what do I need to do messageToSend to send it?
do {
try match.sendData(toAllPlayers: packet, with: .unreliable)
} catch {
}
if error != nil {
// Handle the error.
}
}
func match(_ match: GKMatch, didReceive data: Data, fromRemotePlayer player: GKPlayer) {
//What do I need to do to receive the data?
}
If anyone can help with some working code I can experiment with in Swift 5+ I would be grateful.

After some reading and playing my original code seemed to work!!! If it helps anyone else:
To send:
#IBAction func sendDataBtn(_ sender: Any) {
print("sending data")
let dataString = "Hello, World!"
let dataToSend = dataString.data(using: .utf8)
do {
try myMatch.sendData(toAllPlayers: dataToSend!, with: .reliable)
} catch {
print(error.localizedDescription)
}
}
To receive:
func match(_ match: GKMatch, didReceive data: Data, fromRemotePlayer player: GKPlayer) {
print("Data Received")
let receivedData = String(data: data, encoding: .utf8)
messageLbl.text = receivedData
}

I create a 'container' to send over data, this way I can add an instruction and what needs to be done in one go. For example;
var type:String = "jump"
var data:CGPoint = CGPoint(x:10,y:10)
let container:[Any] = [type, data]
do {
let dataToSend = try NSKeyedArchiver.archivedData(withRootObject: container, requiringSecureCoding: true)
try match.sendData(toAllPlayers: packet, with: .unreliable)
} catch {
}
if error != nil {
// Handle the error.
}

Related

Why isn't my response data being decoded into my type?

My socket sends data to the client. I need to decode the response into this type (Swift):
class Msg: Decodable {
var msg: String
}
my socket code on client (Swift):
socket.on("Message for me") { data, ack in
do {
guard let dict = data[0] as? [String: AnyObject] else { return }
let noti = try JSONSerialization.data(withJSONObject: dict["msg"])
let decoded = try JSONDecoder().decode(Msg.self, from: noti)
print("Message from socket: \(decoded)")
} catch let err {
print(err.localizedDescription)
}
}
my node js server is sending:
io.to(socket.id).emit('Message for me', {msg: `only socket: ${socket.id} can see this`});
I keep getting the following error in my client, and after several tries several different ways I haven't figured out why.
Invalid top-level type in JSON write
I've tried using JSONSerialization.data() and JSONSerialization.jsonObject() and I keep getting the same error. I even checked some of the other similar posts and still nothing. Any help would be appreciated. thanks
After some trial and error, I got it to decode as expected after removing this line:
guard let dict = data[0] as? [String: AnyObject] else { return }.
I guess Swift's serializer and decoder was all that I needed in this instance.

How do I get random number from a function without getting another random number?

I know I worded it kinda weirdly but I'm not entirely sure how to explain it without visuals. I'm sure I'm going about this in a super complicated way. I'm trying to randomly get a Pokemon to spawn in the server to then be able to catch the Pokemon that spawns.
I found the best way to be able to get the name and send the image was to make a few different functions to return each piece that I need at separate places
const Discord = require('discord.js');
const pokemon = require('./pokemon.json');
module.exports = {
getPokemon: function (randomPokemon) {
randomPokemon = pokemon[Math.floor(Math.random() * pokemon.length)];
return randomPokemon;
},
pokemonImage: function (pokeImage) {
pokeImage = new Discord.MessageAttachment((this.getPokemon()).image)
return pokeImage;
},
pokemonName: function (pokeName) {
pokeName = (this.getPokemon()).name;
return pokeName;
},
sendPokemon: function (message) {
return message.channel.send(this.pokemonImage());
}
}
The problem is, when a message is sent, it gets a pokemon and displays it in the server perfectly. But when I go to catch it, I'm calling the pokemonName function which then generates a new random pokemon from the list which instead shows that my answer is wrong.
How do I get the name from the number that was already generated without generating a new random number each time I try to catch them?
Here is the command that is used to catch the Pokemon. Obviously it's grabbing a new random Pokemon every time the command is used but this is where I would like o figure out what I should do.
const { prefix } = require('../config.json');
const functions = require('../functions.js');
module.exports = {
name: 'catch',
description: 'Used to catch a Pokemon that spawns',
execute(message, args) {
args = message.content.slice(prefix.length).split(' ');
if (args[1] == functions.pokemonName()) {
return message.channel.send('That\'s right!');
}else {
message.channel.send('That\'s wrong! Try again.');
}
},
};

Async communicating with serialport gives mixed data

I'm trying to communicating with an arduino that has sensors.
So i have an object called motherboard who has sensors and each sensor has metric which may have threshold and/or polling which has a methode called getValue that sends data to the arduino and returns data with a promise. The problem is that if i async the sensors to get their values all sensors get the same value.
I don't know why this is happening. I only have programmed with javascript for 1 year and with angular for 5 months. I checked the post async/await using serialport in node.js but i checked my code and i did the something that was suggested in the post.
The communicate method is inside a service.
Can anyone help?
tl;dr :
send data to arduino get data back in a promise.
Metric A and B get the same promise.
The component polling also gets the promise of threshold. (metric has threshold and polling)
Me
communication.service.ts
communicate(cmd: string, serialPort: SerialPort, expectedResponse: string, notExpectedResponse){
const parser = serialPort.pipe(new Delimiter({delimiter: '\n'}));
return new Promise((resolve, reject) => {
serialPort.write(cmd, () => {
console.log('message written');
parser.on('data', data => {
const dataString = data.toString();
if (dataString != null && dataString.includes(expectedResponse)) {
let responseRemoved = dataString.replace(expectedResponse + ' ', '');
resolve(responseRemoved);
} else {
let response;
if (dataString != null && dataString.includes(notExpectedResponse)) {
response = dataString.replace(notExpectedResponse + ' ', '');
}
reject(response);
}
});
setTimeout(() => {
reject('');
}, this.timeOutTime);
});
});
}
threshold.component.ts
private getValuesThreshold(): void{
console.log(this.metricId);
this.motherboardInUse.getValues(this.metricId, GlobalVariableCMD.GET_THRESHOLD_VALUES,
GlobalVariableResponse.GET_THRESHOLD_VALUES, GlobalVariableResponse.GET_THRESHOLD_VALUES).then(data => {
let dataString = data.toString();
if(dataString){
console.log(dataString);
let responseSplit = dataString.toString().split(' ');
let minimumValue = parseInt(responseSplit[1]);
let maximumValue = parseInt(responseSplit[2]);
minimumValue < this.floor ? this.minimumThreshold = this.floor : this.minimumThreshold = minimumValue;
maximumValue > this.ceil ? this.maximumThreshold = this.ceil : this.maximumThreshold = 90;
this.enabled = responseSplit[0].includes('1');
console.log(this.minimumThreshold);
console.log(this.maximumThreshold);
console.log(this.enabled);
}
}).catch(err => {
let errString = err.toString();
if(errString){
console.log(errString);
}
});
}
motherboard.component.ts
getValuesThreshold(metricId: string, ATcmd: string, expectedResponse: string, notExpectedResponse: string) {
let command = this.communicateBuilder.BuildCommandGetMetricValue(ATcmd, this.usedSensorId, metricId);
console.log('motherboard get values' + command);
let responseOk = this.commandBuilderService.respondsSuccess(expectedResponse);
let responseNotOk = this.commandBuilderService.respondsFail(notExpectedResponse);
return this.communicateService.communicate(command, this.motherboard.serialPort, responseOk, responseNotOk);
}
Maybe you can try this
async getValuesThreshold(metricId: string, ATcmd: string, expectedResponse: string, notExpectedResponse: string) {
let command = this.communicateBuilder.BuildCommandGetMetricValue(ATcmd, this.usedSensorId, metricId);
console.log('motherboard get values' + command);
let responseOk = this.commandBuilderService.respondsSuccess(expectedResponse);
let responseNotOk = this.commandBuilderService.respondsFail(notExpectedResponse);
return await this.communicateService.communicate(command, this.motherboard.serialPort, responseOk, responseNotOk);
}
The problem was sending async data with serialport.
Serialport node had no way of knowing what response was linked to what data that was send.
So it acted on the first response it got and returned that.
Only way to solve this was to ask them sync.

Flutter_Blue Read response from write

I do not have the Rep to create a tag for Flutter_Blue. But this uses Flutter_Blue in Android Studio.
I am trying to send commands to a device that my company creates devices and I am developing and Android/IOS application that connects to the devices and sends commands and reads what the device returns.
I have transplanted the example code to find devices and then write to them. I have the following code.
_writeCharacteristic(BluetoothCharacteristic c) async {
await device.writeCharacteristic(c, [0x076, 0x0d, 0x0a],
type: CharacteristicWriteType.withResponse);
setState(() {});
}
This sends a v and crlf to a device. How do I read the device response?
Let me know if there is more I need to accomplish this question properly.
I figured it out, See Below
I could be wrong but I found the spot that gets the response i'm looking for.
I Added this
String x = "";
d.forEach((f) => x+=String.fromCharCode(f));
to
_setNotification(BluetoothCharacteristic c) async {
if (c.isNotifying) {
await device.setNotifyValue(c, false);
// Cancel subscription
valueChangedSubscriptions[c.uuid]?.cancel();
valueChangedSubscriptions.remove(c.uuid);
} else {
await device.setNotifyValue(c, true);
// ignore: cancel_subscriptions
final sub = device.onValueChanged(c).listen((d) {
String x = "";
d.forEach((f) => x+=String.fromCharCode(f));
Response = x;
setState(() {
print('onValueChanged $x');
});
});
// Add to map
valueChangedSubscriptions[c.uuid] = sub;
}
setState(() {});
}
and outputs
onValueChanged DT8610CI-7125

How to make nodejs telegram bot to get in row of sertain queries?

I tried to find some answer for this, but got nothing relative. I need to implement something like form as row of Q&A, for example:
U: /form
B: Enter your name
U: John
B: Hello, John. Are you 12 years old?
...
and so on. And I'm going to write answers in Google Spreadsheets, but there's no problem, I just don't know how to create a chain on phrases with bot
Thanks for attention
Okay so the basis of my answer is on a Node library I use for making telegram bots in all my projects. It's called telegram-node-bot, the way other libraries would do it will differ but I like this method cause it lifts all of the heavy load for me and easy to understand.
Here we go:
const Telegram = require('telegram-node-bot');
const TelegramBaseController = Telegram.TelegramBaseController;
const TextCommand = Telegram.TextCommand;
const tg = new Telegram.Telegram('YOUR_TOKEN'); //Ask botfather for your token
class FormController extends TelegramBaseController {
/**
* #param {Scope} $
*/
formHandler($) {
const form = {
name: {
q: 'Send me your name',
error: 'Sorry, wrong input',
validator: (message, callback) => {
const answer = message.text;
if (answer) {
callback(true, answer);
return
}
callback(false);
}
},
age: {
q: 'Send me your age',
error: 'sorry, wrong input',
validator: (message, callback) => {
const answer = message.text;
if (answer && IsNumeric(answer)) {
callback(true, toInt(answer))
return
}
callback(false)
}
}
}
$.runForm(form, (result) => {
console.log(result)
})
}
get routes() {
return {
'formCommand': 'formHandler'
}
}
}
tg.router
.when(
new TextCommand('/form', 'formCommand'),
new FormController()
)
The logic/algorithm behind it is simple:
Ask a question.
Wait for a response.
Check if the response fits the criterias you've set for the right answer format
If false ask the question again.
If true move to the next question.

Resources