- Shop features.
- New event whisperFail.
- New function client.leaveTribe and client.tribe.leave.
- New event tribeInvite.
- New function client.answerTribeInvite.
- sigterm is handled correctly for all clients now.
- New event languageSet.
- updatePlayer now receives a third argument related to the field that has been updated.
- New event shaman.
- Field
Map.perm
has been renamed to Map.permCode
.
- Event newGame now receives a parameter
map
with the Map class.
- Events joinTribeHouse and roomChanged now receive a parameter
room
with the Room class.
- Event receivedPacket now receives the following parameters: (identifiers, packet, connection)
- Event receive has been renamed to receivedPacket.
- Event missedPacket has been renamed to unhandledPacket.
- Event missedTribulle has been renamed to unhandledTribullePacket.
- client.changeWhisperState(message, state) is now client.changeWhisperState(state, message)
- Parameter of the event roomChanged "isPrivate" is now "isOfficial", meaning that if you relied on this boolean, please negate it now.
- Event connection is now triggered when the first bulle connection is set (zero arguments)
- New event mainConnection that is triggered when the main connection is set (takes all arguments from connection)
- Event ping is now serverPing.
- Client.insertPacketListener, Client.insertOldListener are now Client.insertModernListener, Client.insertLegacyListener, respectively.
- Client.parsePacket is now Client.triggerPacketCallback.
- Client.closeAll is now Client.killConnections.
- Event _receive no longer exists, it's all handled by receive now.
- enum.setting.mainIp is now enum.setting.mainIP.
- _Encode.identificationKeys and _Encode.messageKeys are now in Client.
- _Client.gameVersion is now enum.setting.gameVersion
- _Client.processXml, Client.processXml has been renamed to _Client.decryptXML, Client.decryptXML, respectively.
- Client.community, Client.setCommunity, enum.community have been renamed to Client.language, Client.setLanguage, enum.language, respectively.
- Event tribeInterface now receives only one object parameter Tribe.
- Event connectionInfo has been renamed to accountDataLoaded.
- Event playerDied has been renamed to playerDeath.
- Event missedOldPacket has been renamed to unhandledLegacyPacket.
- client.main, client.bulle, client.hbTimer, _client.receivedAuthkey, client.connectionTime, _client.hasSpecialRole, have been renamed to client.mainConnection, client.bulleConnection, _client.heartbeatTimer, _client.authenticationKey, _client.loginTime, _client.isOfficialBot, respectively.
- connection.open, connection.port has been renamed to connection.isOpen, connection.portIndex, respectively.
- When a player becomes shaman, the event shaman will be triggered instead of updatePlayer.
- connection has been renamed to Connection.
- Translation.download is not the class' constructor.
- Translation is now a class.
- translation has been renamed to Translation.
- encode is not a class anymore.
- buffer has been renamed to Buffer.
- bitwise has been renamed to bit64.
- byteArray has been renamed to ByteArray.
- Connection.receive now correctly handles long packets
- The ready event now receives a new parameter language which in the future may vary.
- Handle language receive/send due to internal changes of the game.
- Changed how translations were getting split due to internal changes of the game.
- string.split has a new implementation. Now it receives a separator instead of a negation pattern. Example: '%S+ is now '%s'.
You still can use the old version with string.split2 by using the following chunk:
--[[@
@name string.split2
@desc Splits a string into parts based on a pattern.
@param str<string> The string to be split.
@param pat<string> The pattern to split the string. Note that it doesn't auto-include '[^%s]'
@returns table The data of the split string.
]]
string.split2 = function(str, pat)
local out, counter = { }, 0
for v in string.gmatch(str, pat) do
counter = counter + 1
out[counter] = tonumber(v) or v
end
return out
end
- byteArray.write24's alias byteArray.writeInt was named byteArray.writeWrite. Same for read.
- Change keys endpoint
- Remove mapArray because it's not used anymore
- ByteArray performance slightly improved
- Added method client.waitFor to await an event emission.
client:on("whisperMessage", function(playerName, message)
if message == "cheese" then
client:sendCommand("profile " .. playerName)
local success, playerData = client:waitFor("profileLoaded", 1000, function(playerData)
return playerData.playerName == playerName
end)
if success then
client:sendWhisper(playerName, "You have " .. playerData.cheese .. " cheese!")
end
end
end)
- New IDs in enum.identifier.
- Added event tribeInterface ( tribeName, tribeMembers, tribeRanks, tribeHouseMap, greetingMessage, tribeId).
- Added method client.openTribeInterface.
- Added method client.acceptTribeHouseInvitation.
- Added event tribeHouseInvitation ( inviterName, inviterTribe ).
- Added event serverReboot ( msTime ).
- Added method client.enterPrivateRoom.
- ByteArray is now read-only or write-only. You cannot mix it. With that, read functions got ~35x faster.
- Connection wouldn't reset properly if needed. (Fix connectionFailed reconnection)
- Closing the command prompt/terminal or process should close all pending connections correctly now, thus avoiding firewall bans.
- New IDs in enum.roomMode.
- Switching bulles won't extract the bulle id anymore, but uid and pid.
- Removed parameter bulleId from the event switchBulleConnection.
- Ports are now set in (44, 1), since this information is received there.
- Switched enum.roomMode.defilante with enum.roomMode.music.
- Added method client.setTribeGreetingMessage
- New event playerEmoticon ( playerData, emoticon ).
- PacketID is not set on login anymore.
- Errors will not be thrown anymore when getKey cannot retrieve data from the endpoint if the account is a bot.
- Added the internal function client.stopHandlingPlayers.
- Allow UserBots to use the API.
- Two new fields in client object: _hasSpecialRole and _updateSettings.
- Two new parameters in client.new: hasSpecialRole and updateSettings.
- Update IP and Ports with the endpoint content.
- Improve byteArray's performance.
- New enum url.
- _client.who_fingerprint has been renamed to _client.whoFingerprint.
- _client.who_list has been renamed to _client.whoList.
- _client.process_xml has been renamed to _client.processXml.
- _client.handle_players has been renamed to _client._handlePlayers.
- encode.lua is now a class.
- encode.getPasswordHash is a static function.
- encode.btea and encode.xorCipher are now class functions.
- setPacketKeys has been removed.
- New event connectionInfo ( playerData, friendList, soulmate, blackList, tribeData ).
- New parameter added to switchBulleConnection: serverTimestamp.
- The roomList event now has the community value for each table of @rooms/@pinned.
- New protocol system for the new protocol system of the game.
- Minor optimizations in the code.
- Added function byteArray.readSigned16.
- The translation methods will now return booleans based on whether the action happened or not.
- The autoupdater system should be fixed.
- Likes of cafe messages were not working properly due to unsigned shorts.
- Added new parameters in the event ready:
onlinePlayers
, community
, country
.
- Added new parameters in the event connection:
playerName
, community
, playerId
, playedTime
.
- Added the event bulleSwitchConnection ( bulleId, bulleIp )
- Changing room would disconnect the bots due to a bulle connection change that has been implemented internally in the game.
- Now you can call the client constructor passing the parameters
tfmId
and token
so that it automatically calls the start function.
- The method client.openCafe would not work correctly.
- Fixed weird require behavior depending on the operational system.
(i hope)
- Added the event playerEmote( playerData, emote, flag ).
- The append parameter in the insertion methods were not working.
- Removed the handler of lit OS glitch. Lua's require, BURN IN HELL
- __tostring metamethod in byteArray.
- Fixed some login issues due to the new connection system. (google, facebook, etc)
- Windows vs Linux require behavior was in conflict. Now it handles both.
- Transformice's IP and Ports have changed. All previous versions won't work unless these values get edited in the enumerations.
New IP = 94.23.193.229
New ports = 13801, 11801, 12801, 14801
- connection.send would trigger an error when the socket was closed.
- Small glitch in the alias system.
- Pray for the connection memory leak, an undo was necessary...
- Added transfromage.version.
- Added the metamethod __pairs in client.playerList so it can iter over string indexes only.
-- How to use client.playerList
-- An event that returns a player id
client:on("removeFriend", function(playerId)
if client.playerList[playerId] then
print("You removed the player '" .. client.playerList[playerId].playerName .. "' from your friend list. This player is in your room.")
end
end)
-- Iter over the players
local names = { }
for player = 1, #client.playerList do
names[player] = client.playerList[player].playerName
end
print("Players in the room: " .. table.concat(names, ", "))
-- Iter over their names (same code as above, but with an extra comma :)
print("Players in the room: ")
for k, v in pairs(client.playerList) do -- pairs is necessary to trigger __pairs
io.write(v.playerName .. ", ")
end
- Added two helpers for readability and to avoid using private fields: client.handlePlayers, client.processXml_
- Added a small alias / compatibility system through table.setNewClass.
- Renamed client.closeAll to client.disconnect, but kept compatibility.
- Fixed a possible memory leak from connection. 🤔
- playerList[i]._pos is not to as stable as it seemed to be, a fix might come soon but for now it'll ignore invalid indexes.
- client.playerList wouldn't refresh when the account changed the room.
- bArray.writeBigUtf would not work when the input was string.
- Added enum.game.
- Added the private function handleFriendData.
- Added the event removeFriend ( playerId ).
- Added the event newFriend ( friend ).
- Added the event blackList ( blackList ).
- Added client.whitelistPlayer.
- Added client.blacklistPlayer.
- Added client.removeFriend.
- Added client.addFriend.
- Added client.requestBlackList.
- Added a new data value for the parameters of the event friendList,
gameId
.
- Now the field from the handleFriendData playerName has its nickname normalized with string.toNickname.
- client._process_xml was set to true as default.
- Added the event connectionFailed ( ).
- Added a new parameter in translation.download, now it accepts a function to execute after the file download.
- client.start can now be called more than once.
- Now the internal function getKeys is not deleted after client.start is called.
- The timed out constant problems were reduced.
- Now the field from the event profileLoaded soulmate has its nickname normalized with string.toNickname.
- Added the event friendList ( friendList, soulmate ).
- Added client.requestFriendList.
- Added optimization variables.
- translation.free wouldn't work correctly when both whitelist parameters were set simultaneously.
- Renamed the private function coroutineFunction to coroutine.makef.
- Added translation.download, translation.get and translation.free.
- Added the file translation.lua.
- Added string.utf8.
- table.copy now cover tables.
- Now invalid enumerations, using an error handler that ignores low level ones, won't break the client functions anymore.
- Added the internal function client.coroutineFunction.
- All insert functions now execute automatic coroutine callbacks. (@f is now coroutinized).
- Added the function os.log.
- Added the function connection.close.
- Added the function client.reloadCafe.
- The field client._cafe was renamed to client.cafe.
- Implemented error system (low and high error) with the enum of enum.errorLevel. Now you can rewrite the function error to handle low and high errors differently. Example:
do
local err = error
error = function(message, level)
if level == transfromage.enum.errorLevel.low then
return os.log("↑failure↓ERROR↑ " .. message) -- Colorful print with the FAILURE warning.
else
return error(message, level)
end
end
end
- Added internal function client.handlePlayerField.
- Added a new parameter
append
in the listener functions.
- Added table.copy.
- Added the event refreshPlayerList ( playerList ).
- Added the event updatePlayer ( playerData, oldPlayerData ).
-- All the facilities events (playerGetCheese, playerVampire, etc) can be hard-coded using this main-event.
-- Example:
client:on("updatePlayer", playerData, oldPlayerData)
if playerData.hasCheese and not oldPlayerData.hasCheese then
client:emit("playerGetCheese", playerData, true)
elseif oldPlayerData.hasCheese and not playerData.hasCheese then
client:emit("playerGetCheese", playerData, false)
end
end)
- Added the event newPlayer ( playerData ).
- Added the event playerGetCheese ( playerData, hasCheese ).
- Added the event playerVampire ( playerData, isVampire ).
- Added the event playerWon ( playerData, position, timeElapsed ).
- Added the event playerLeft ( playerData ).
- Added the event playerDied ( playerData ).
- Added math.normalizePoint.
- Added enum.errorLevel.
- Added table.setNewClass.
- Added enum.error.
- Added enum._validate.
- The sequence order of parameters in the listener functions have changed.
- insertTribulleListener's f → (packet, connection, tribulleId)
- insertOldPacketListener's f → (data, connection, oldIdentifiers)
- insertPacketListener's f → (packet, connection, identifiers)
- Now you don't need to send client.openCafe to reload it. Use client.reloadCafe instead.
- Renamed the tables trib, oldPkt, and exec in Client.lua. They are now called tribulleListener, oldPacketListener and packetListener, respectively.
- Renamed the class connectionHandler to connection.
- Renamed the enum emote.:D to emote.laugh, due to facilities. No compatibility maintained.
- Renamed the enum identifier.message to identifier.bulle, since it was a grotesque mistake since the beginning. No compatibility maintained.
- Renamed the enum identifier.bulle to identifier.bulleConnection. No compatibility maintained because it was an internal enum.
- Added the function client.closeAll, a brute-force to trigger the real and private closeAll function.
- Removed client.gamePacketKeys. It was never used.
- The functions client.parsePacket, client.receive, client.getKeys, client.sendHeartbeat, client.closeAll are now private, since their use could compromise the functionalities of the API.
- Renamed the function encode.encodeChunks to encode.btea. No compatibility maintained.
- Renamed the file cipher to encode.
- The following client fields were renamed to private fields:
- mainLoop → _mainLoop
- bulleLoop → _bulleLoop
- receivedAuthkey → _receivedAuthkey
- gameVersion → _gameVersion
- gameConnectionKey → _gameConnectionKey
- gameIdentificationKeys → _gameIdentificationKeys
- gameMsgKeys → _gameMsgKeys
- Renamed enum._checkEnum to enum._exists. No compatibility maintained because it was an internal function.
- End of compatibility of enum._enum. Use the constructor enum() instead.
- The sequence of the parameters in the events missedPacket, missedTribulle, and missedOldPacket have all changed. Now, the connection parameter is the last one.
- client.on and client.once now have automatic coroutine callbacks.
- The event disconnection would trigger twice when the main socket got disconnected.
- client._connectionTime was wrongly set before the login.
- table.join was broken.
- Added the event unreadCafeMessage ( topicId, topic ).
-- Usually should be used as
client:on("unreadCafeMessage", function(topicId, topic)
client:openCafeTopic(topicId)
end)
- Added client.openCafeTopic.
- Added client.createCafeTopic.
- Added client.likeCafeMessage.
- Added client.sendCafeMessage.
-- Tools for sending messages
local quoteCafeMessage = function(message)
return "> @" .. message.author .. "\r> " + message.content + "\r\r"
end
local replyCafeMessage = function(message, content)
client:sendCafeMessage(message.topicId, quoteCafeMessage(message.content) .. content)
end
- Added the event cafeTopicMessage ( message, topic ).
- Added the event cafeTopicLoad ( topic ).
- Added the event cafeTopicList ( data ).
- Added client.openCafe.
- Added the event roomList ( roomMode, rooms, pinned ).
- Added enum.roomMode.
- Added client.requestRoomList.
- Added client.insertOldPacketListener.
- Added the event missedOldPacket ( connection, identifiers, packet ).
- Now the API supports old packets (1, 1).
- The insertFuction functions were renamed. However the compatibility was kept. (Please, open an issue if you find any problem related to it)
- insertReceiveFunction → insertPacketListener
- insertTribulleFunction → insertTribulleListener
- The event missedPacket now receives the parameter connection.
- The event tribeMemberGetRole was passing the parameters memberName and setterName in a wrong order.
- It was missing some normalization for player names and uncoded strings in some events.
- Added client.setTribeMemberRole.
- Added the event tribeMemberGetRole ( memberName, setterName, role ).
- Added the event friendConnection ( playerName ).
- Added the event friendDisconnection ( playerName ).
- Added the event tribeMemberConnection ( memberName ).
- Added the event tribeMemberDisconnection ( memberName ).
- Added the event tribeMemberKick ( memberName, kickerName ).
- Added client.kickTribeMember.
- The documentation is now reorganised.
- Events are not documented in the source files.
- The order of the port numbers has been changed aiming better connections.
- Due to memory consumption the variable
_process_xml
is now exposed so you can enable or disable the XML processes. Default value is true. Set it as false if you are not using the event newGame.
client._process_xml = false
- Added the event newGame ( map ).
- Added client.recruitPlayer.
- The ByteArray functions were renamed. However the compatibility was kept. (Please, open an issue if you find any problem related to it)
- readByte → read8
- write8 → write8
- readShort → read16
- writeShort → write16
- readInt → read24
- writeInt → write24
- readLong → read32
- writeLong → write32
- The emoticon enumeration was wrong.
- Added the event tribeMemberLeave ( memberName ).
- Added the event newTribeMember ( memberName ).
- Added the event time ( time ).
- Added client.connectionTime.
- Added the function string.toNickname ( str, checkDiscriminator ).
- Added the event chatWho ( chatName, data ).
- Added the event missedTribulle ( connection, tribulleId, packet ).
- Added client.insertTribulleFunction.
- Added client.chatWho.
- Added the event tribeMessage ( memberName, message ).
- Added client.sendTribeMessage.
- The order of parameters of the receive event changed. ( connection, identifiers, packet )
- The private function fixEntity is now string.fixEntity.
- Renamed the file
byteArray.lua
to bArray.lua
due to Heroku compatibility issues.
- Improved the packet struct of client.loadLua.
- Added client.emit.
- Now the cipher class can be used from the require.
require('transfromage').encode
- Added the event staffList ( list ).
- Added client.insertReceiveFunction.
- Added a new parameter
timeout
in client.connect.
- The function string.getBytes could break if it was too big.
- When someone sent the character
<
it was accidentally replaced by >
.
- Added a new update system:
semiautoupdate
, that asks for permission before updating the API.
- Added client.playEmoticon.
- Added client.playEmote.
- Added the event profileLoaded ( data ).
- Fixed an enumeration problem in changeWhisperState.
- Added the message error when the endpoint keys fail.
- Added the
time
argument in the ping event.
- Added the event ping ( ).
- Added the event lua ( log ).
- Fixed
community
and chatCommunity
enums.
- The events will translate every
&
to &
now.
- Added client.loadLua.
- Added the event tribeMessage ( memberName, message ).
- Added client.sendTribeMessage.
- Added client.changeWhisperState.
- Added enum.whisperState.
- The events will translate every
<
to <
now.
- Improved the error messages when an enum is not provided correctly in the functions.
- Initial room was set to
nil
instead of *#bolodefchoco
if no value was provided.
- Now the byteArray class can be used from the require.
require('transfromage').byteArray
- Now the connection event is triggered after 5s since the login, not 2s. It prevents many bulle bugs.
- Added an error message when the tfmkey or token parameters are invalid in
Client.start
.
- byteArray.writeBool was incorrect.
- File byteArray was named bytearray and it could throw an error without the luvit require module.
- The private event _socketConnection was receiving a nil value as parameter. (port)
- The
autoupdate
system was not working.
- Release version. Connection stable.