Javascript Unique Array for each Socket User - javascript

i have a Problem!
When two users playing a game and they click very near at the same time, all two users get what only the 2nd user must get.
Is it possible to make an array by his userid or something?
I also have for anti spam like that
anti_spam[socket.request.session.passport.user.id]
But thats a json
If i try the same or array, i get error SyntaxError: Unexpected token [
How can i make sure, that each user get only his own items and not items from another user when opening at the same time?
I use sockets, here is a unique userid socket.request.session.passport.user.id
This is the array
var WinItem = [];
And if two users start like milliseconds same time, than the second overwrite the first...

! CODE NOT TESTED!
Wait wait wait wait...
So I only know ws (Node.js) but there you first get a onConnection event.
In that function you add a UID to the connection element. Then if you receive a message from the client you should have you're connection object and therefore an UID. You now can store the won item in the connection object (if you want) maybe like so:
ws.onConnection = con => {
con.UID = generateUID();
con.inventory = [];
con.onMessage = msg => {
[..STUFF/CODE/YAY...]
con.inventory.push(item);
con.send("You've won wooohoo");
});
});
Did you mean something like this??
Otherwise please be more specific about what you want.
(You can also store the stuff somewhere else together with the UID but that would add quiet some code)

Related

Showing the number of folders in a given place

why is my code not working? I want to do something like that when the bot turns on I get a message to the console about the number of servers it is in.
const serversFolders = readdirSync(dirServers)
const servers = parseInt(serversFolders)
table.addRow(servers)
console.log(table.toString())
If you want to display the number of servers your bot is in simply do:
console.log(client.guilds.cache.size);

How to emit an array that updates across connected clients with socket.io

I'm trying to display the usernames of all connected clients in my chat room by adding their username to an array. Currently, my code will just update the user-list with the most recent username to have joined, rather than add the username to the array, leading me to believe the array isn't actually being emitted in the way I anticipate?
script.js:
var items = [];
var user = user;
if (!user) {
user = prompt('Please choose a username:');
items.push(user);
socket.emit('theitems', {
items: items
});
if (!user) {
alert('Your name has been set to "Anonymous"');
user = "Anonymous"
items.push(user);
} else {
alert('Your name has been set to "'+ user +'"');
}
}
console.log(items);
socket.on('theitems', function (data) {
$('.dispUser').html(data.items);
});
index.js
server(socket('theitems', ctx => { console.log(ctx.data); ctx.io.emit('theitems', ctx.data); }));
Updated code that uses the server as a 'master array'.
This code (+ some of the above) has solved my issue.
index.js (server):
var newitems = [];
server(socket('theitems', ctx => { newitems.push(ctx.data); console.log(ctx.data); ctx.io.emit('theitems', newitems); }));
script.js (client):
socket.emit('theitems', user);
socket.on('theitems', function (data) {
$('.dispUser').html(data);
console.log(data);
});
Sorry; my idea is that there’s an array (items[]) that stores the usernames of clients as they join and leave, and displays that array to a , so, that, as clients join and leave, their usernames are displayed/removed, aka, an “online users” section.
To do that, you have two choices. Whenever the array changes on the server you have to either send a new copy of the full array of names to each client and they then update their entire user list display or you tell them exactly which user has been removed or added and they then incrementally update their display based on the change.
To send the whole array to one specific socket, you would do something like this:
socket.emit('userList', userArray);
To send it to all connected uses, you would do this:
io.emit('userList', userArray);
In both cases, the client would listen for the 'userList' message and then update their display accordingly.
socket.on('userList', userArray => {
// refresh the display to show the userArray
});
It's simple, just socket.emit('eventName', array);
But if you change items of array, it's not gonna change in all socket clients and/or server. You need to emit new array every time that array has changed. Otherwise sockets are not gonna update their values

Pushing Elements to a JSON Array with Braces

I am having a hard time trying to push elements to a JSON file located in an external location; here's a backstory on what I am trying to achieve:
I am programming a private Discord bot and am currently working on the message-system portion of it. The whole idea is that a user's message is deleted if they aren't fully authorized onto the server; that user's message and UserID will be logged into the JSON file . The thing is, I can only log the message if a UserID is manually added to the array (using the push function, I can add the message). But, if I try to push a UserID to the file array, it acts as if the push function does not exist for this; I think the JSON is nested as well. I would appreciate any help I can get, thanks!
JSON
{"users":[{}]}
I want to put the UserID within the braces inside the brackets
Code to push to the JSON
function removeMessage(content, authorid) {
if (!messagedata.users[0][authorid]) {
messagedata.users[0].push(authorid);
}
}
Current I'm Getting:
TypeError: messagedata.users[0].push is not a function
Expected Output
{"users":[{"287423028147781654":["Hi"]}]}
The numerical value is the UserID, while 'Hi' is clearly the message
users[0] is an object, not an array (and hence has no push method). It appears you actually want to add a key to the object, so try this instead:
messagedata.users[0][authorid] = ["Hi"];

Double indexing in associative array

I'm building a server using Node.js. I store the objects representing my users in an associative array and right now the index of those objects are the sockets id of that connection. Using the Socket.io library i obtain it by simply doing socket.id, so for each handler that takes care of my requests I can always know which user made the request.
Client-side every user has the ids of the connected users (that are different from the socket ids).
The problem araises when i have an handler that is used to send a message from an user to another, i make an example:
User A needs to send a message to user B, my protocol specifies the message as something like this:
MSG_KEY:{MSG:'hello world',USER_ID:'12345'}
Server-side i have an handler that listens to "MSG_KEY" and when the message is sent it is executed and using the socket.id I can retrieve who made the request, but the problem is that i need to get also the user B but this time using his USER_ID. I don't want to use the socket.id to avoid session spoofing.
I first thought about indexing in my array the users by indexing them both from socket.id and user id.
My question is: is it a good idea to do this? Does socket.io provide a way to simplify this?
There's no particular reason you can't do that. I would use two separate objects (maps), and probably have the users be represented by objects rather than strings so that there was really only one user (referenced from two places).
E.g., a user:
var user = {userid: "JohnD", name: "John Doe"};
and then:
var usersByID = {};
usersByName[user.userid];
and
var usersBySocket = {};
usersBySocket[theSocketID] = user;
Or even
var users = {
byID: {},
bySocket: {}
};
users.byID[user.userid] = user;
users.bySocket[theSocketID] = user;

How do I get the same format for a javascript array and django set on the backend?

I have code that, when a user is logged in, selects recipes that apply to him based on the ingredients (items) he has previously identified identified as possessions.
This code gets the id's of the items the user already has:
if request.user.is_authenticated():
user_items = [possession.item for possession in request.user.possession_set.all()]
user_items_ids = [item.id for item in user_items]
uids = set(user_items_ids)
The following code, which already existed, is where I run into problems...
recipes = [(recipe, len(set([item.id for item in recipe.items.all()]) & uids), recipe.votes) for recipe in recipes]
I created another part of the site that allows people who have not yet signed up to just pick a few ingredients. I do this with some jQuery on the front end, then send the results to the backend:
var ingredient_set = [];
$('.temp_ingredient').each(function(index){
ingredient_set[index] = $(this).attr('id').substr(4);
});
$.get('/recipes/discover', { 'ingredients': ingredient_set },
function(){
alert("Success");
});
The problem is when I receive them on the Django side, with this code:
uids = request.GET['ingredients']
I get the following error:
unsupported operand type(s) for &: 'set' and 'unicode'
Basically, I know they aren't in the same format, but I don't know how to get them to be compatible.
You are sending a JavaScript array in the query string of your GET request. Therefore you should use request.GET.getlist. Just using request.GET[key] gives you the last value for that key.
>> request.GET['foo[]']
u'5'
>> request.GET.getlist('foo[]')
[u'1', u'2', u'4', u'5']
Note that the values are unicode, but you probably need them as integers, so be sure to convert them.
uids = request.GET.getlist('foo[]')
uids = set([int(x) for x in uids])
I'm not sure why my key is actually foo[] and not just foo, but as you get no KeyError, request.GET.getlist('ingredients') should work.

Categories