I've been using the YouMax plugin which enables you to embed your YouTube channel on your website. However, I am having problems as it displays the uploaded date in months and years. I'd like it to display days, weeks, months and years.
You can view the source code here http://jsfiddle.net/wCKKU/
I believe that its this that needs adjusting to make it calculate in day, weeks, months and years.
function getDateDiff(timestamp) {
if (null == timestamp || timestamp == "" || timestamp == "undefined") return "?";
var splitDate = ((timestamp.toString().split('T'))[0]).split('-');
var d1 = new Date();
var d1Y = d1.getFullYear();
var d2Y = parseInt(splitDate[0], 10);
var d1M = d1.getMonth();
var d2M = parseInt(splitDate[1], 10);
var diffInMonths = (d1M + 12 * d1Y) - (d2M + 12 * d2Y);
if (diffInMonths <= 1) return "1 month";
else if (diffInMonths < 12) return diffInMonths + " months";
var diffInYears = Math.floor(diffInMonths / 12);
if (diffInYears <= 1) return "1 year";
else if (diffInYears < 12) return diffInYears + " years"
}
You could modify the plugin by a small block of code in the middle of the function:
var d2M = parseInt(splitDate[1], 10); // this line is already there
var d1D = d1.getDate();
var d2D = parseInt(splitDate[2],10);
var diffInDays = (d1D + 30 *d1M + 12 * d1Y) - (d2D + 30 *d2M + 12 *d2Y);
if (diffInDays < 2) return "1 day";
else if (diffInDays < 7) return diffInDays+" days";
else if (diffInDays > 7 && diffInDays < 14) return "1 week";
else if (diffInDays > 14 && diffInDays < 30) return Math.floor(diffInDays / 7) + " weeks";
var diffInMonths = (d1M + 12 * d1Y) - (d2M + 12 * d2Y); // this line is already there
Note that this isn't a particularly elegant way to handle the issue, but it matches the coding style the plugin is already using, and at least won't break anything else.
Also, as a side comment, if you're modifying the plugin code you'll want to fix a bug in it at the same time. Getting the current month should look like this:
var d1M = d1.getMonth() + 1;
This is because in Javascript, the getMonth() function returns the month on a zero-based index, and your math won't be reliable unless you switch it to a one-based index.
Related
I have a relatively basic set of code here that is programmed to roll 3 dice and give me the results whenever I type "/roll" in discord.
However, the results displayed on my command terminal are always different from those in the discord message from the bot.
async execute(interaction)
{
var num = 3;
num = Number(num);
function rollingDice(num) {
// make the dice rolling "num" times.
// return the results.
var diceResults = "";
for (var i = 0; i < num; i++) {
var resultOfEachDice = "";
resultOfEachDice = Math.floor((Math.random() * 6) + 1);
diceResults += resultOfEachDice + ", ";
}
var lastComma = diceResults.lastIndexOf(", ");
diceResults = diceResults.slice(0, lastComma);
return diceResults;
}
var diceResults = rollingDice()
console.log("Rolled " + num + " dice: " + rollingDice(num));
console.log(process.argv);
await interaction.reply('You rolled: ' + rollingDice(num));
So I will type /roll and my terminal will say I rolled "3, 5, 2" while the message would have something entirely different like "1, 6, 4".
This happens every time I run the command and I am not sure what the issue is.
GAS is quite powerful and you could write a full fledged web-app using a Google Sheet as the DB back-end. There are many reasons not to do this but I figure in some cases it is okay.
I think the biggest issue will be performance issues when looking for rows based on some criteria in a sheet with a lot of rows. I know there are many ways to "query" a sheet but I can't find reliable information on which is the fastest.
One of the complexities is that many people can edit a sheet which means there are a variable number of situations you'd have to account for. For the sake of simplicity, I want to assume the sheet:
Is locked down so only one person can see it
The first column has the row number (=row())
The most basic query is finding a row where a specific column equals some value.
Which method would be the fastest?
I have a sheet with ~19k rows and ~38 columns, filled with all sorts of unsorted real-world data. That is almost 700k rows so I figured it would be a good sheet to time a few methods and see which is the fastest.
method 1: get sheet as a 2D array then go through each row
method 2: get sheet as a 2D array, sort it, then using a binary search algorithm to find the row
method 3: make a UrlFetch call to Google visualization query and don't provide last row
method 4: make a UrlFetch call to Google visualization query and provide last row
Here are the my query functions.
function method1(spreadsheetID, sheetName, columnIndex, query)
{
// get the sheet values excluding header,
var rowValues = SpreadsheetApp.openById(spreadsheetID).getSheetByName(sheetName).getSheetValues(2, 1, -1, -1);
// loop through each row
for(var i = 0, numRows = rowValues.length; i < numRows; ++i)
{
// return it if found
if(rowValues[i][columnIndex] == query) return rowValues[i]
}
return false;
}
function method2(spreadsheetID, sheetName, columnIndex, query)
{
// get the sheet values excluding header
var rowValues = SpreadsheetApp.openById(spreadsheetID).getSheetByName(sheetName).getSheetValues(2, 1, -1, -1);
// sort it
rowValues.sort(function(a, b){
if(a[columnIndex] < b[columnIndex]) return -1;
if(a[columnIndex] > b[columnIndex]) return 1;
return 0;
});
// search using binary search
var foundRow = matrixBinarySearch(rowValues, columnIndex, query, 0, rowValues.length - 1);
// return if found
if(foundRow != -1)
{
return rowValues[foundRow];
}
return false;
}
function method3(spreadsheetID, sheetName, queryColumnLetterStart, queryColumnLetterEnd, queryColumnLetterSearch, query)
{
// SQL like query
myQuery = "SELECT * WHERE " + queryColumnLetterSearch + " = '" + query + "'";
// the query URL
// don't provide last row in range selection
var qvizURL = 'https://docs.google.com/spreadsheets/d/' + spreadsheetID + '/gviz/tq?tqx=out:json&headers=1&sheet=' + sheetName + '&range=' + queryColumnLetterStart + ":" + queryColumnLetterEnd + '&tq=' + encodeURIComponent(myQuery);
// fetch the data
var ret = UrlFetchApp.fetch(qvizURL, {headers: {Authorization: 'Bearer ' + ScriptApp.getOAuthToken()}}).getContentText();
// remove some crap from the return string
return JSON.parse(ret.replace("/*O_o*/", "").replace("google.visualization.Query.setResponse(", "").slice(0, -2));
}
function method4(spreadsheetID, sheetName, queryColumnLetterStart, queryColumnLetterEnd, queryColumnLetterSearch, query)
{
// find the last row in the sheet
var lastRow = SpreadsheetApp.openById(spreadsheetID).getSheetByName(sheetName).getLastRow();
// SQL like query
myQuery = "SELECT * WHERE " + queryColumnLetterSearch + " = '" + query + "'";
// the query URL
var qvizURL = 'https://docs.google.com/spreadsheets/d/' + spreadsheetID + '/gviz/tq?tqx=out:json&headers=1&sheet=' + sheetName + '&range=' + queryColumnLetterStart + "1:" + queryColumnLetterEnd + lastRow + '&tq=' + encodeURIComponent(myQuery);
// fetch the data
var ret = UrlFetchApp.fetch(qvizURL, {headers: {Authorization: 'Bearer ' + ScriptApp.getOAuthToken()}}).getContentText();
// remove some crap from the return string
return JSON.parse(ret.replace("/*O_o*/", "").replace("google.visualization.Query.setResponse(", "").slice(0, -2));
}
My binary search algorithm:
function matrixBinarySearch(matrix, columnIndex, query, firstIndex, lastIndex)
{
// find the value using binary search
// https://www.w3resource.com/javascript-exercises/javascript-array-exercise-18.php
// first make sure the query string is valid
// if it is less than the smallest value
// or larger than the largest value
// it is not valid
if(query < matrix[firstIndex][columnIndex] || query > matrix[lastIndex][columnIndex]) return -1;
// if its the first row
if(query == matrix[firstIndex][columnIndex]) return firstIndex;
// if its the last row
if(query == matrix[lastIndex][columnIndex]) return lastIndex;
// now start doing binary search
var middleIndex = Math.floor((lastIndex + firstIndex)/2);
while(matrix[middleIndex][columnIndex] != query && firstIndex < lastIndex)
{
if(query < matrix[middleIndex][columnIndex])
{
lastIndex = middleIndex - 1;
}
else if(query > matrix[middleIndex][columnIndex])
{
firstIndex = middleIndex + 1;
}
middleIndex = Math.floor((lastIndex + firstIndex)/2);
}
return matrix[middleIndex][columnIndex] == query ? middleIndex : -1;
}
This is the function I used to test them all:
// each time this function is called it will try one method
// the first time it is called it will try method1
// then method2, then method3, then method4
// after it does method4 it will start back at method1
// we will use script properties to save which method is next
// we also want to use the same query string for each batch so we'll save that in script properties too
function testIt()
{
// get the sheet where we're staving run times
var runTimesSheet = SpreadsheetApp.openById("...").getSheetByName("times");
// we want to see true speed tests and don't want server side caching so we a copy of our data sheet
// make a copy of our data sheet and get its ID
var tempSheetID = SpreadsheetApp.openById("...").copy("temp sheet").getId();
// get script properties
var scriptProperties = PropertiesService.getScriptProperties();
// the counter
var searchCounter = Number(scriptProperties.getProperty("searchCounter"));
// index of search list we want to query for
var searchListIndex = Number(scriptProperties.getProperty("searchListIndex"));
// if we're at 0 then we need to get the index of the query string
if(searchCounter == 0)
{
searchListIndex = Math.floor(Math.random() * searchList.length);
scriptProperties.setProperty("searchListIndex", searchListIndex);
}
// query string
var query = searchList[searchListIndex];
// save relevant data
var timerRow = ["method" + (searchCounter + 1), searchListIndex, query, 0, "", "", "", ""];
// run the appropriate method
switch(searchCounter)
{
case 0:
// start time
var start = (new Date()).getTime();
// run the query
var ret = method1(tempSheetID, "Extract", 1, query);
// end time
timerRow[3] = ((new Date()).getTime() - start) / 1000;
// if we found the row save its values in the timer output so we can confirm it was found
if(ret)
{
timerRow[4] = ret[0];
timerRow[5] = ret[1];
timerRow[6] = ret[2];
timerRow[7] = ret[3];
}
break;
case 1:
var start = (new Date()).getTime();
var ret = method2(tempSheetID, "Extract", 1, query);
timerRow[3] = ((new Date()).getTime() - start) / 1000;
if(ret)
{
timerRow[4] = ret[0];
timerRow[5] = ret[1];
timerRow[6] = ret[2];
timerRow[7] = ret[3];
}
break;
case 2:
var start = (new Date()).getTime();
var ret = method3(tempSheetID, "Extract", "A", "AL", "B", query);
timerRow[3] = ((new Date()).getTime() - start) / 1000;
if(ret.table.rows.length)
{
timerRow[4] = ret.table.rows[0].c[0].v;
timerRow[5] = ret.table.rows[0].c[1].v;
timerRow[6] = ret.table.rows[0].c[2].v;
timerRow[7] = ret.table.rows[0].c[3].v;
}
break;
case 3:
var start = (new Date()).getTime();
var ret = method3(tempSheetID, "Extract", "A", "AL", "B", query);
timerRow[3] = ((new Date()).getTime() - start) / 1000;
if(ret.table.rows.length)
{
timerRow[4] = ret.table.rows[0].c[0].v;
timerRow[5] = ret.table.rows[0].c[1].v;
timerRow[6] = ret.table.rows[0].c[2].v;
timerRow[7] = ret.table.rows[0].c[3].v;
}
break;
}
// delete the temp file
DriveApp.getFileById(tempSheetID).setTrashed(true);
// save run times
runTimesSheet.appendRow(timerRow);
// start back at 0 if we're the end
if(++searchCounter == 4) searchCounter = 0;
// save the search counter
scriptProperties.setProperty("searchCounter", searchCounter);
}
I have a global variable searchList that is an array of various query strings -- some are in the sheet, some are not.
I ran testit on a trigger to run every minute. After 152 iterations I had 38 batches. Looking at the result, this is what I see for each method:
| Method | Minimum Seconds | Maximum Seconds | Average Seconds |
|---------|-----------------|-----------------|-----------------|
| method1 | 8.24 | 36.94 | 11.86 |
| method2 | 9.93 | 23.38 | 14.09 |
| method3 | 1.92 | 5.48 | 3.06 |
| method4 | 2.20 | 11.14 | 3.36 |
So it appears that, at least for my data-set, is using Google visualization query is the fastest.
I need to calculate the total job experience as year value. Users add experiences with starting and ending dates to their resumes, just like Linkedin. But there is no any certain pattern. For instance;
A user may have a resume like that;
Experience 2
08.2012 - 01.2015
Experience 1
01.2011 - 01.2013
The user started their second experience while the first hasn't finished yet. So resumes may have many overlapping experiences. Overlapping also may occur between more than 2. So I need to consider many cases.
I tried to visualise the experience and year relationship for you.
I just need to develop an algorithm covering all the cases for this issue.
Sort by start date
start at the beginning and accumulate overlapping experiences (i.e. treat as one)
e.g. (Jan 2012, Jan 2015), (Jan 2014, Dec 2016) overlap, so we treat it as a single experience
This "super experience" begins at the start of the first, and ends at the end of the last; (Jan 2012, Dec 2016)
This is assuming that there can be gaps in experience, so we don't want to treat the entire history as one long "super experience"
I just did this
Sort the experiences by Begin Date.
Use 2 variables, that represent the begin of work and the end called Begin
and End.
If end and begin are empty it means that is the first date, we filled with the first experience, and we calculate the month count between the begin and end of this experience and and then this months count add to our months accumulator.
if the end and begin date of next experience is not between our begin and end variables, we calculate the months count from the experience and then add it to our accumulator.
If the begin date of next experience is between our begin and end variables, we calculate the months count between our end date as begin and the experience end date as end, and then that difference add to our months accumulator.
as you can see every time we set our new end if the experience end is greater than ours.
at the end we get the months, if you divide by 12 you get the years exactly you can round it if you want
NOTE: I Mapped the experiences, if not have End it means that is equivalent to NOW
you can see all the code below
function monthDiff(d1, d2) {
var m = (d1.getFullYear() - d2.getFullYear()) * 12 +
(d1.getMonth() - d2.getMonth());
if (d1.getDate() < d2.getDate()) --m;
return m;
}
function dateCheck(from, to, check) {
var fDate, lDate, cDate;
fDate = Date.parse(from);
lDate = Date.parse(to);
cDate = Date.parse(check);
if (cDate <= lDate && cDate >= fDate) {
return true;
}
return false;
}
function calculateYearsOfExperience(experiences) {
if (!experiences) return 0;
let months = 0;
let now = new Date();
let sorted = experiences
.sort((a, b) => {
return new Date(a.begin) - new Date(b.begin);
})
.map(experience => {
if (!experience.end) experience.end = now;
return { begin: experience.begin, end: experience.end };
});
let begin;
let end;
for (var i in sorted) {
let dif = 0;
if (!end && !begin) {
dif = monthDiff(sorted[i].begin, sorted[i].end);
begin = sorted[i].begin;
end = sorted[i].end;
} else if (
!dateCheck(begin, end, sorted[i].begin) &&
!dateCheck(begin, end, sorted[i].end)
) {
dif = monthDiff(sorted[i].begin, sorted[i].end);
end = sorted[i].end;
} else if (dateCheck(begin, end, sorted[i].begin)) {
dif = monthDiff(end, sorted[i].end);
end = sorted[i].end;
}
months += dif;
}
return months / 12;
}
experiences = [
# (start date, end date),
(date(2012, 8, 1), date(2015, 1, 30)),
(date(2011, 1, 1), date(2013, 1, 30))
]
print(sum((end_date - start_date).days/365 for start_date, end_date in experiences))
Create an array full of 0. Element range: Start would be the very first hire date, last would be current date / last working date. For every year you have 12 elements that can be 0/1. After filling in the array count the elements that have the value 1. If you need to take into account the overlapping then ignore the 0/1 part and give +1 for every month worked.
This is c# code, but you'll get the steps in algorithm. It returns total number of months which you can convert into year and month format.
var sortedList = expList
.OrderBy(a => a.start_year)
.ThenBy(a => a.start_month)
.ThenBy(a => a.end_year)
.ThenBy(a => a.end_month)
.ToList();
int totalMonths = 0;
int totalDays = 0;
DateTime? prevEndDate = null;
foreach (var exp in sortedList)
{
if(exp.start_month != null && exp.start_year != null)
{
var startDate = new DateTime((int)exp.start_year, (int)exp.start_month, 1);
var endDate = (bool)exp.is_present ?
DateTime.Now :
new DateTime((int)exp.end_year, (int)exp.end_month, 1);
if (prevEndDate != null && prevEndDate > startDate)
{
startDate = (DateTime)prevEndDate;
}
var timespan = endDate.Subtract(startDate);
var tempdate = DateTime.MinValue + timespan;
totalMonths = totalMonths + (tempdate.Year - 1) * 12 + tempdate.Month - 1;
totalDays = totalDays + tempdate.Day - 1;
prevEndDate = endDate;
}
}
if (totalDays > 0)
{
totalMonths = totalMonths + 1;
}
public static function YearCalculation($id=null) {
if($id=="")
$employee_id=#Auth::guard('web_employee')->user()->id;
else
$employee_id=$id;
$employee_exp = Experience::where('employee_id',$employee_id)->orderBy("experience_from","ASC")->get();
//print_r($employee_exp ); exit;
$years = 0;
$months = 0;
$days = 0;
$sum=0;
$lastfromdate=0;
$last_endDate=0;
if(#$employee_exp!=null){
foreach(#$employee_exp as $experience){
$fdate = #$experience->experience_from;
if($experience->is_current==0){
$tdate = #$experience->experience_to;
}else{
$tdate = date("Y-m-d");
}
if($last_endDate != date("Y-m-d") ){
if( $fdate < $last_endDate ){
$start_date1 = strtotime($last_endDate);
$end_date1 = strtotime($tdate);
$interval1 = ($end_date1 - $start_date1)/60/60/24;
$sum +=$interval1;
}
else{
$start_date2 = strtotime($fdate);
$end_date2 = strtotime($tdate);
$interval2 = ($end_date2 - $start_date2)/60/60/24;
$sum +=$interval2;
}
if($last_endDate < $tdate){
$last_endDate=$tdate;
}
}
}
$years = ($sum / 365) ;
$years = floor($years);
$month = ($sum % 365) / 30.4166;
$month = floor($month);
$days = ($sum % 365) % 30.4166;
//$total=date_diff(0,$tmstamp);
//$total_year=$years.' years, ' .$month.' months and '.$days.($days==1?' day':' days');
$total_year=($years==0?'':($years==1?$years.' year':$years.' years and ')) .($month==0?'':($month==1?$month.($days>1?'+':'').' month':$month.($days>1?'+':'').' months'));
return $total_year;
}
}
I have StartDate (for instance 2011-01-01) and EndDate (for instance 2011-12-31).
All my data are placed in this range.
In test plan I need to generate random interval with fixed duration
(for 4 cases: 1, 3, 7 days and 1 month long)
which are placed in this date range [2011-01-01; 2011-12-31].
Each of these cases must have defined weights.
How should I do to get fixed interval with random Start Date and random End Date (and put these random dates into 2 variables)?
I have found this variant of java-script
The initial script is here:
var startDate = new Date();
startDate.setDate(1);
startDate.setMonth(0);
startDate.setYear(1991);
var startDateTime = startDate.getTime();
var endDate = new Date();
endDate.setDate(31);
endDate.setMonth(11);
endDate.setYear(2003);
var endDateTime = endDate.getTime();
var randomDate = new Date();
var randomDateTime = startDateTime+Math.random()*(endDateTime-startDateTime);
randomDate.setTime(randomDateTime);
var rndDate = randomDate.getDate();
var rndMonth = randomDate.getMonth() + 1;
var rndYear = randomDate.getFullYear();
if (rndDate.toString().length == 1)
rndDate = "0" + rndDate;
if (rndMonth.toString().length == 1)
rndMonth = "0" + rndMonth;
rndDate + "/" + rndMonth + "/" + rndYear;
But I need generate random start date of the fixed interval (which I called ${RandomStartDate}) and then to add the length of the interval to get the end date of it (this date I called ${RandomEndDate}).
Then I have change the script for 1 day long interval (1 day is 86400 seconds):
var startDate = new Date();
startDate.setDate(01);
startDate.setMonth(01);
startDate.setYear(2011);
var startDateTime = startDate.getTime();
var endDate = new Date();
endDate.setDate(31);
endDate.setMonth(12);
endDate.setYear(2011);
var endDateTime = endDate.getTime();
var randomSDate = new Date();
var randomSDateTime = startDateTime+Math.random()*((endDateTime - 86400) -startDateTime );
randomSDate.setTime(randomSDateTime);
var randomEDate = new Date();
var randomEDateTime = (randomSDateTime + 86400); //add 1 day long interval (86400 s)
randomEDate.setTime(randomEDateTime); //convert number format to string format of date
var rndSDate = randomSDate.getDate();
var rndSMonth = randomSDate.getMonth()+1 ;
var rndSYear = randomSDate.getFullYear();
var rndEDate = randomEDate.getDate();
var rndEMonth = randomEDate.getMonth()+1 ;
var rndEYear = randomEDate.getFullYear();
if (rndSDate.toString().length == 1)
rndSDate = "0" + rndSDate;
if (rndSMonth.toString().length == 1)
rndSMonth = "0" + rndSMonth;
if (rndEDate.toString().length == 1)
rndEDate = "0" + rndEDate;
if (rndEMonth.toString().length == 1)
rndEMonth = "0" + rndEMonth;
var RandomStartDate = rndSYear + "-" + rndSMonth + "-" + rndSDate;
vars.put ("RandomStartDate", RandomStartDate);
var RandomEndDate = rndEYear + "-" + rndEMonth + "-" + rndEDate;
vars.put ("RandomEndDate", RandomEndDate);
But this script generates RandomEndDate which is equal to RandomStartDate.
If I generate RandomStartDate separately (without the parts of code which are connected with RandomEndDate) the script works good.
Could you help me, please? What is wrong?
You can do it in Beanshell with much less amount of code:
import java.text.SimpleDateFormat;
import java.util.Calendar;
calendar = Calendar.getInstance();
calendar.set(2011, 0, 1);
startTime = calendar.getTimeInMillis();
calendar.set(2012, 11, 31);
endTime = calendar.getTimeInMillis();
randomTime1 = startTime + (long)(Math.random()*(endTime-startTime));
randomTime2 = randomTime1 + (long)(Math.random()*(endTime - randomTime1)+86400000);
formatter = new SimpleDateFormat("yyyy-MM-dd");
calendar.setTimeInMillis(randomTime1);
vars.put("start", formatter.format(calendar.getTime()));
calendar.setTimeInMillis(randomTime2);
vars.put("end", formatter.format(calendar.getTime()));
For situations like this I would opt to put the complexity outside of jMeter, and create a perl script to generate 100 pairs of dates according to your requirements and read them into jMeter variables using CSV Data Set Config.
I have found the solution!
This is the correct script, which allow to model the random interval with fixed length (1 day long interval) and get 2 variables fot it start and end - ${RandomStartDate} and ${RandomEndDate}:
var startDate = new Date();
startDate.setDate(01);
startDate.setMonth(01);
startDate.setYear(2011);
var startDateTime = startDate.getTime();
var endDate = new Date();
endDate.setDate(31);
endDate.setMonth(12);
endDate.setYear(2011);
var endDateTime = endDate.getTime();
var randomSDate = new Date();
var randomSDateTime = startDateTime+Math.random()*((endDateTime - 86400000) -startDateTime );
randomSDate.setTime(randomSDateTime);
var randomEDate = new Date();
var randomEDateTime = (randomSDateTime + 86400000); //add 1 day long interval (86400000 ms)
randomEDate.setTime(randomEDateTime); //convert number format to string format of date
var rndSDate = randomSDate.getDate();
var rndSMonth = randomSDate.getMonth()+1 ;
var rndSYear = randomSDate.getFullYear();
var rndEDate = randomEDate.getDate();
var rndEMonth = randomEDate.getMonth()+1 ;
var rndEYear = randomEDate.getFullYear();
if (rndSDate.toString().length == 1)
rndSDate = "0" + rndSDate;
if (rndSMonth.toString().length == 1)
rndSMonth = "0" + rndSMonth;
if (rndEDate.toString().length == 1)
rndEDate = "0" + rndEDate;
if (rndEMonth.toString().length == 1)
rndEMonth = "0" + rndEMonth;
var RandomStartDate = rndSYear + "-" + rndSMonth + "-" + rndSDate;
vars.put ("RandomStartDate", RandomStartDate);
var RandomEndDate = rndEYear + "-" + rndEMonth + "-" + rndEDate;
vars.put ("RandomEndDate", RandomEndDate);
My mistake was I thought that the time is in seconds, but it is in milliseconds!
I am working on a game in Construct2 at the moment.
It is a HTML5 Javascript Engine.
I probably implement clay.io inside it.
My question however is about "Rooms"
Clay.io also helps with Rooms. However I am not sure If I will take that offer.
https://clay.io/docs/rooms
So when I want to limit the users per game to 10 for example. Would I then need to run two servers?
The socket.io server recives and returns data.. But would two games running with each 10 people not confuse the servers data? When person A on server A shoots some1, that this information could somehow end up on Person B on server B?
Or do the assigned ID's prevent this somehow?
Here is the Example Server that I want to upgrade for my needs:
var entities = [], count = 0;
var io = require("socket.io").listen(8099);
var INITIAL_X = 5;
var INITIAL_Y = 5;
var INITIAL_VEL_X = 0;
var INITIAL_VEL_Y = 0;
io.set('log level', 1);
io.sockets.on("connection", function (socket) {
var myNumber = count++;
//assign number
var mySelf = entities[myNumber] = [myNumber, INITIAL_X, INITIAL_Y, INITIAL_VEL_X, INITIAL_VEL_Y];
//Send the initial position and ID to connecting player
console.log(myNumber + ' sent: ' + 'I,' + mySelf[0] + ',' + mySelf[1] + ',' + mySelf[2]);
socket.send('I,' + mySelf[0] + ',' + mySelf[1] + ',' + mySelf[2]);
//Send to conencting client the current state of all the other players
for (var entity_idx = 0; entity_idx < entities.length; entity_idx++) {
//send initial update
if (entity_idx != myNumber) {
entity = entities[entity_idx];
if (typeof (entity) != "undefined" && entity != null) {
console.log(myNumber + ' sent: C for ' + entity_idx);
socket.send('C,' + entity[0] + ',' + entity[1] + ',' + entity[2]);
//send the client that just connected the position of all the other clients
}
}
}
//create new entity in all clients
socket.broadcast.emit("message",
'C,' + mySelf[0] + ',' + mySelf[1] + ',' + mySelf[2]);
socket.on("message", function (data) {
//if (myNumber == 0)
// console.log(myNumber + ' sent: ' +data);
var new_data = data.split(',');
if (new_data[0] == 'UM') {
mySelf[1] = new_data[1];
mySelf[2] = new_data[2];
mySelf[3] = new_data[3];
mySelf[4] = new_data[4];
//Update all the other clients about my update
socket.broadcast.emit("message",
'UM,' + mySelf[0] + ',' + mySelf[1] + ',' + mySelf[2] + ',' + mySelf[3] + ',' + mySelf[4]);
}
else if (new_data[0] == 'S') { // a s message
var shoot_info = [];
shoot_info[0] = new_data[1]; //ini x
shoot_info[1] = new_data[2]; //ini y
shoot_info[2] = new_data[3]; //degrees
//Update all the other clients about my update
socket.broadcast.emit("message",
'S,' + mySelf[0] + ',' + shoot_info[0] + ',' + shoot_info[1] + ',' + shoot_info[2]);
}
});
});
Socket.io has rooms that you can limit the broadcasts to, see: https://github.com/LearnBoost/socket.io/wiki/Rooms
Then rather than use socket.broadcast.emit you would use io.sockets.in('roomname').emit
A good way to mesh this with Clay.io is to have the room name be the room.id (in the Construct 2 plugin that's the RoomId expression). When the Clay.io room fills up (in C2 there's a condition for that), create the Socket.io room using that unique ID and put the players who "Rooms Filled" was just called for in that room.
I know it's a bit different since it's a game written in CoffeeScript instead of Construct 2, but we're using Clay.io rooms + Socket.io rooms in our Slime Volley game. Here is the code.