[QUOTE=UnkN;50087399]I [have] not found [two players with the] same uniqueIDs.[/QUOTE]
Neither have I, but the collision finders some coders have made show that this really is a serious problem.
This is the kind of problem that you aren't likely to see by running your 32 player server. This is what some people see over the entire gmod community.
The biggest problem with having UniqueID changed to SteamID64 is that for DarkRP at least, everyone would lose their data.
The problem in DarkRP goes a bit further. Braxen has this really nice solution of gradually migrating to SteamID64. This works for him, but I fear for all the addons that speak to the database directly. I don't know how many of those there are, but those who have it will break.
[QUOTE=FPtje;50087937]Neither have I, but the collision finders some coders have made show that this really is a serious problem.
This is the kind of problem that you aren't likely to see by running your 32 player server. This is what some people see over the entire gmod community.
The biggest problem with having UniqueID changed to SteamID64 is that for DarkRP at least, everyone would lose their data.
The problem in DarkRP goes a bit further. Braxen has this really nice solution of gradually migrating to SteamID64. This works for him, but I fear for all the addons that speak to the database directly. I don't know how many of those there are, but those who have it will break.[/QUOTE]
Give a deprecation warning?
Actually uniqueid precaches? What about if we precache it
[QUOTE=gonzalolog;50088309]Actually uniqueid precaches? What about if we precache it[/QUOTE]
The precaching thing was a clientside only bug if I recall, regardless, that was fixed.
A deprecation warning is not enough for DarkRP "developers"
[QUOTE=BillyOnWiiU;50088376]A deprecation warning is not enough for DarkRP "developers"[/QUOTE]
good
[QUOTE=BillyOnWiiU;50088376]A deprecation warning is not enough for DarkRP "developers"[/QUOTE]
It's enough for anyone. Anyone who chooses to ignore it gets left behind.
I don't know why this community has such a backwards view on changing things and maintaining backwards compatibility. It seems like every change we make, there has to be a safety net for people to keep their ancient, should-be-dead addons running.
Deprecate something for one update, then on the next update, remove it.
[QUOTE=Revenge282;50088418]It's enough for anyone. Anyone who chooses to ignore it gets left behind.
I don't know why this community has such a backwards view on changing things and maintaining backwards compatibility. It seems like every change we make, there has to be a safety net for people to keep their ancient, should-be-dead addons running.
Deprecate something for one update, then on the next update, remove it.[/QUOTE]
There's a good reason for that. Backwards compatibility is important. If someone made a useful tool back in 2014, but has since then completely forgotten about GMod, then what happens? If an update breaks it, then we just lost a good addon. "Should-be-dead"? Who's to say?
[QUOTE=Neat-Nit;50089029]There's a good reason for that. Backwards compatibility is important. If someone made a useful tool back in 2014, but has since then completely forgotten about GMod, then what happens? If an update breaks it, then we just lost a good addon. "Should-be-dead"? Who's to say?[/QUOTE]
In most cases some random fella picks it up and fixes it and puts it on Workshop labeled "Fixed Version", thats how it always has been, even in the old garrysmod.org days.
[URL="http://extrem-team.com/hl2_160405_crash_2016_4_7T22_59_12C0.mdmp"]Crash while generating some icons on dev branch[/URL]
Edit : yeah, keep crashing on this icon, in prop_destruction
On another topic, I randomly came across table.IsSequential and couldn't help but notice it's wrongly implemented: [url]https://github.com/garrynewman/garrysmod/blob/master/garrysmod/lua/includes/extensions/table.lua#L172[/url]
Current code:
[Lua]function table.IsSequential( t )
local i = 1
for key, value in pairs( t ) do
if ( !tonumber( i ) || key != i ) then return false end
i = i + 1
end
return true
end[/Lua]
One problem is that pairs() is not guaranteed to give sequential keys in sequential tables (aka arrays). So this code might return false for a sequential table.
Another problem is that whoever wrote this was drunk and no one proof-read it. if ( !tonumber( i ) || key != i ) - what the hell is this. tonumber is used like isnumber, and is ran on i which is always a number. So really it only checks if key equals i.
I know I should probably put this in a pull request, but I feel like I might be missing something which is why I'm putting it here instead. My suggested fix:
[Lua]function table.IsSequential( t )
local max = 0
local count = 0
for k, _ in pairs( t ) do
if !isnumber( k ) then return false end
if k < 1 then return false end
if k != math.floor(k) then return false end -- non-integer key
if k > max then max = k end
count = count + 1
end
return count == max
end[/Lua]
This ensures that:
1. All keys are integers
2. All keys between 1 and max are present
even if pairs does not return them in the correct order.
Edit: and it returns true for empty tables, as did the old code.
[QUOTE=Neat-Nit;50089675]On another topic, I randomly came across table.IsSequential and couldn't help but notice it's wrongly implemented: [url]https://github.com/garrynewman/garrysmod/blob/master/garrysmod/lua/includes/extensions/table.lua#L172[/url]
Current code:
[Lua]function table.IsSequential( t )
local i = 1
for key, value in pairs( t ) do
if ( !tonumber( i ) || key != i ) then return false end
i = i + 1
end
return true
end[/Lua]
One problem is that pairs() is not guaranteed to give sequential keys in sequential tables (aka arrays). So this code might return false for a sequential table.
Another problem is that whoever wrote this was drunk and no one proof-read it. if ( !tonumber( i ) || key != i ) - what the hell is this. tonumber is used like isnumber, and is ran on i which is always a number. So really it only checks if key equals i.
I know I should probably put this in a pull request, but I feel like I might be missing something which is why I'm putting it here instead. My suggested fix:
[Lua]function table.IsSequential( t )
local max = 0
local count = 0
for k, _ in pairs( t ) do
if !isnumber( k ) then return false end
if k < 1 then return false end
if k != math.floor(k) then return false end -- non-integer key
if k > max then max = k end
count = count + 1
end
return count == max
end[/Lua]
This ensures that:
1. All keys are integers
2. All keys between 1 and max are present
even if pairs does not return them in the correct order.
Edit: and it returns true for empty tables, as did the old code.[/QUOTE]
The original's meant to be !tonumber( key ) I believe.
And it should be type( key ) != "number"
[QUOTE=Neat-Nit;50089675]On another topic, I randomly came across table.IsSequential and couldn't help but notice it's wrongly implemented: [url]https://github.com/garrynewman/garrysmod/blob/master/garrysmod/lua/includes/extensions/table.lua#L172[/url]
Current code:
[Lua]function table.IsSequential( t )
local i = 1
for key, value in pairs( t ) do
if ( !tonumber( i ) || key != i ) then return false end
i = i + 1
end
return true
end[/Lua]
One problem is that pairs() is not guaranteed to give sequential keys in sequential tables (aka arrays). So this code might return false for a sequential table.
Another problem is that whoever wrote this was drunk and no one proof-read it. if ( !tonumber( i ) || key != i ) - what the hell is this. tonumber is used like isnumber, and is ran on i which is always a number. So really it only checks if key equals i.
I know I should probably put this in a pull request, but I feel like I might be missing something which is why I'm putting it here instead. My suggested fix:
[Lua]function table.IsSequential( t )
local max = 0
local count = 0
for k, _ in pairs( t ) do
if !isnumber( k ) then return false end
if k < 1 then return false end
if k != math.floor(k) then return false end -- non-integer key
if k > max then max = k end
count = count + 1
end
return count == max
end[/Lua]
This ensures that:
1. All keys are integers
2. All keys between 1 and max are present
even if pairs does not return them in the correct order.
Edit: and it returns true for empty tables, as did the old code.[/QUOTE]
I've probably missed the point, but it sounds like you could just use table.sort, could you not?
That would put all of your key value pairs in order, obviously, which might fix your problem. Then just do a numerical for loop and check like that
[QUOTE=Z0mb1n3;50089802]I've probably missed the point, but it sounds like you could just use table.sort, could you not?
That would put all of your key value pairs in order, obviously, which might fix your problem. Then just do a numerical for loop and check like that[/QUOTE]
Depends if you want to check for "holes" in the table or not.
couldn't that entire function be changed to
[code]
return table.Count( tab ) == #tab
[/code]
the # operator will only return the amount of sequential indexes in the table, if there's a discrepancy between that and table.Count( tab ) then the table is not sequential
[editline]7th April 2016[/editline]
not entirely sure if table.Count works the way I think it does though
[QUOTE=FPtje;50087937]The biggest problem with having UniqueID changed to SteamID64 is that for DarkRP at least, everyone would lose their data.
but I fear for all the addons that speak to the database directly. I don't know how many of those there are, but those who have it will break.[/QUOTE]
transitioning over to steamid64 isn't hard, just check the length of the data (17 for steamid64) and migrate it at runtime, that's what i've been doing for everything pretty much, and i have a reverse lookup table
but yes that other concern is a deal breaker
[QUOTE=Joeyl10;50090106]couldn't that entire function be changed to
[code]
return table.Count( tab ) == #tab
[/code]
the # operator will only return the amount of sequential indexes in the table, if there's a discrepancy between that and table.Count( tab ) then the table is not sequential
[editline]7th April 2016[/editline]
not entirely sure if table.Count works the way I think it does though[/QUOTE]
According to the lua standard, #table returns any of the returns from this function:
luajit does not always return the first n sequential things, it returns something from here:
[lua]
]function len(t)
local possible_returns = {};
if(nil == t[1]) then
table.insert(possible_returns, 0);
end
for k,v in pairs(t) do
if(type(k) == "number" and k % 1 == 0 and k > 0 and t[k+1] == nil) then
table.insert(possible_returns, k);
end
end
return possible_returns;
end
[/lua]
[editline]a[/editline]
this would be the 'proper' code:
[lua]
function is_sequential(t)
local max = 0
for k in pairs(t) do
if (type(k) ~= "number" or k % 1 ~= 0 or k < 1) then
return false
end
max = math.max(k, max)
end
for i = 1, max do
if (not t[i]) then
return false
end
end
return true
end
[/lua]
You forgot a "do" in the first loop of your proper code meep.
[QUOTE=YourStalker;50091036]You forgot a "do" in the first loop of your proper code meep.[/QUOTE]
proper lua needs no do
Am I the only one who uses SteamID3? Is there something wrong with using it?
[QUOTE=zeaga;50091221]Am I the only one who uses SteamID3? Is there something wrong with using it?[/QUOTE]
I don't see any default gmod function for it. You'd have to make your own function, which is a bother.
Some explanation about SteamID3:
[url]http://forums.steampowered.com/forums/showpost.php?p=35768152&postcount=4[/url]
[QUOTE=FPtje;50091636]I don't see any default gmod function for it. You'd have to make your own function, which is a bother.[/QUOTE]
I mean, yeah, but it's stupid easy to write one.
But what's wrong with SteamID32?
[QUOTE=Joeyl10;50090106]couldn't that entire function be changed to
[code]
return table.Count( tab ) == #tab
[/code]
the # operator will only return the amount of sequential indexes in the table, if there's a discrepancy between that and table.Count( tab ) then the table is not sequential
[editline]7th April 2016[/editline]
not entirely sure if table.Count works the way I think it does though[/QUOTE]
the # operator is ill-defined for non-sequential tables. Even if this works, it would be bad practice to use it this way.
Additionally, table.Count iterates over the whole table no matter what. My code finishes the loop and returns immediately if it finds a non-sequential index, without pointlessly going over the rest of the table.
[editline]8th April 2016[/editline]
[QUOTE=MeepDarknessM;50090382]According to the lua standard, #table returns any of the returns from this function:
luajit does not always return the first n sequential things, it returns something from here:
[lua]
]function len(t)
local possible_returns = {};
if(nil == t[1]) then
table.insert(possible_returns, 0);
end
for k,v in pairs(t) do
if(type(k) == "number" and k % 1 == 0 and k > 0 and t[k+1] == nil) then
table.insert(possible_returns, k);
end
end
return possible_returns;
end
[/lua]
[editline]a[/editline]
this would be the 'proper' code:
[lua]
function is_sequential(t)
local max = 0
for k in pairs(t) do
if (type(k) ~= "number" or k % 1 ~= 0 or k < 1) then
return false
end
max = math.max(k, max)
end
for i = 1, max do
if (not t[i]) then
return false
end
end
return true
end
[/lua][/QUOTE]
And how is that code better than mine? isnumber is more elegant than type() == "number", and you have a pointless for loop which I nicely avoid. Because you see, if all keys are integers, and the can't be a repeated key (because there can't), and the keys are sequential, then the count of the keys has to be equal to the maximum key. If there was any hole, the count would be smaller than max. And it's impossible for count to be bigger than max.
Oh and by the way, a sequential table can have boolean values, and if t[3] = false then your code would return false.
[editline]8th April 2016[/editline]
To be honest I'm not really sure if this function is ever used, I think you would always know whether your table is sequential or not. But it exists, it might as well work correctly.
Have a question that seems trivial at first:
What makes a lua table with arbitrary keys sequential?
Does it mean that there exists a way to loop over it in such way that the keys are seen sequentially? Or must we demand that the keys that "pairs" finds, must be sequential? pairs is a specific, but rather arbitrary way of looping over the table, but if the order given by pairs is not what must be considered sequential, then what is?
[QUOTE=FPtje;50091995]Have a question that seems trivial at first:
What makes a lua table with arbitrary keys sequential?
Does it mean that there exists a way to loop over it in such way that the keys are seen sequentially? Or must we demand that the keys that "pairs" finds, must be sequential? pairs is a specific, but rather arbitrary way of looping over the table, but if the order given by pairs is not what must be considered sequential, then what is?[/QUOTE]
Hmm... I assumed it just meant an array. Now you've made me doubt myself.
If you want to iterate over an array you use ipairs instead of pairs, this guarantees that it loops in order.
[QUOTE=Neat-Nit;50092012]Hmm... I assumed it just meant an array. Now you've made me doubt myself.
If you want to iterate over an array you use ipairs instead of pairs, this guarantees that it loops in order.[/QUOTE]
Arrays in some languages allow "holes". Sequential tables are usually defined as not having them AFAIK.
[QUOTE=Bo98;50092017]Arrays in most languages allow "holes". Sequential tables are usually defined as not having them AFAIK.[/QUOTE]
Depends what you mean by 'most languages', the languages I know don't allow holes.
By the way, proof of concept that pairs doesn't guarantee sequence: [img]https://i.gyazo.com/9e4d6cf73d9b0bed9ac2580d358888e4.png[/img]
Are you wanting to ignore or deny non-numeric keys?
[QUOTE=http://www.lua.org/manual/5.3/manual.html#3.4.7]
Note, however, that non-numeric keys do not interfere with whether a table is a sequence.
[/QUOTE]
[QUOTE=Neat-Nit;50092012]Hmm... I assumed it just meant an array. Now you've made me doubt myself.
If you want to iterate over an array you use ipairs instead of pairs, this guarantees that it loops in order.[/QUOTE]
Let me explain my philosophical question with some examples:
[lua]
a = {}
a[1] = true
a[5] = true
a[3] = true
[/lua]
Is this table sequential? Why?
There exists an order through which one can sequentially iterate over the table, but if [I]that[/I] is how one judges whether a table is sequential, then any table that doesn't hold tables, entities or functions (and maybe some other types) as keys will be sequential. After all, any table with keys for which one can define an ordering will have an ordering.
Should we define IsSequential, As Bo suggeted, as not having holes?
Then this table would be sequential:
[lua]
a = {}
a[1] = true
a[2] = true
a[3] = true
[/lua]
But this one would not:
[lua]
a = {}
a[1] = true
a[2] = true
a[4] = true
[/lua]
Also, should we demand that the lowest key in sequential tables MUST be 1? If we do, then this table would [U]not [/U]be considered sequential:
[lua]
a = {}
a[0] = true
a[1] = true
[/lua]
Or should you define IsSequential as whether all the keys seen by pairs are sequential? (this one is obviously a bad idea, since your screenshot shows that this would return arbitrary values)
Consider the following implementation:
[lua]
function IsSequential(tbl) return #tbl == table.Count(tbl) end
[/lua]
This implementation demands that all keys between 1 and #tbl exist and that all keys of the table are actually in that range. It's very strict, but useful in Lua. IsSequential returning true would mean you can loop over it with ipairs without missing any values. It means you're sure that there exists no non-number keys in the table.
Still, IsSequential would be a bad name, because not all sequential tables would be considered sequential. IsArray would perhaps be a better term. Fuck the terminology, though. Backwards compatibility.
Sorry, you need to Log In to post a reply to this thread.