diff --git a/game/engines/default/engine/UserChat.lua b/game/engines/default/engine/UserChat.lua
index 5ed3c3b0acf5f7c3e56066709e7b9875f44cf3c2..1fa683638c7bba296b134632dfd76e5e6a855c3d 100644
--- a/game/engines/default/engine/UserChat.lua
+++ b/game/engines/default/engine/UserChat.lua
@@ -73,14 +73,14 @@ function _M:event(e)
 		self.channels[e.channel] = self.channels[e.channel] or {users={}, log={}}
 		self.channels[e.channel].users[e.login] = {name=e.name, login=e.login}
 		self.channels_changed = true
-		self:addMessage(e.channel, e.user, "#{italic}##FIREBRICK#has joined the channel#{normal}#")
-		if type(game) == "table" and game.log and e.channel == self.cur_channel then game.log("#{italic}##FIREBRICK#%s has joined channel %s (press space to talk).#{normal}#", e.user, e.channel) end
+		self:addMessage(e.channel, e.login, e.name, "#{italic}##FIREBRICK#has joined the channel#{normal}#")
+		if type(game) == "table" and game.log and e.channel == self.cur_channel then game.log("#{italic}##FIREBRICK#%s has joined channel %s (press space to talk).#{normal}#", e.login, e.channel) end
 	elseif e.se == "Part" then
 		self.channels[e.channel] = self.channels[e.channel] or {users={}, log={}}
 		self.channels[e.channel].users[e.login] = nil
 		self.channels_changed = true
-		self:addMessage(e.channel, e.user, "#{italic}##FIREBRICK#has left the channel#{normal}#")
-		if type(game) == "table" and game.log and e.channel == self.cur_channel then game.log("#{italic}##FIREBRICK#%s has left channel %s.#{normal}#", e.user, e.channel) end
+		self:addMessage(e.channel, e.login, e.name, "#{italic}##FIREBRICK#has left the channel#{normal}#")
+		if type(game) == "table" and game.log and e.channel == self.cur_channel then game.log("#{italic}##FIREBRICK#%s has left channel %s.#{normal}#", e.login, e.channel) end
 	elseif e.se == "UserInfo" then
 		local info = e.data:unserialize()
 		if not info then return end
diff --git a/game/profile-thread/Client.lua b/game/profile-thread/Client.lua
index f773c7aa41cb9028918ea0aff7cd65b088903845..96ced480faf6e8a3c6e409ebab163a9591df0c09 100644
--- a/game/profile-thread/Client.lua
+++ b/game/profile-thread/Client.lua
@@ -328,6 +328,13 @@ function _M:orderChatJoin(o)
 	end
 end
 
+function _M:orderChatPart(o)
+	self:command("Part", o.channel)
+	if self:read("200") then
+		self.chat:parted(o.channel)
+	end
+end
+
 function _M:orderChatUserInfo(o)
 	self:command("UINF", o.user)
 	if self:read("200") then
diff --git a/game/profile-thread/UserChat.lua b/game/profile-thread/UserChat.lua
index a153ff1c9ffc036e384bc05ed7c95633e69ae3f4..68f9d7e8e32ef59f4c2ccf3562ba3ccab0e52cd3 100644
--- a/game/profile-thread/UserChat.lua
+++ b/game/profile-thread/UserChat.lua
@@ -25,33 +25,41 @@ module(..., package.seeall, class.make)
 function _M:init(client)
 	self.client = client
 	self.channels = {}
-	self.joined = {}
+	self.cjoined = {}
 end
 
 function _M:event(e)
 	if e.e == "ChatTalk" then
 		cprofile.pushEvent(string.format("e='Chat' se='Talk' channel=%q login=%q name=%q msg=%q", e.channel, e.login, e.name, e.msg))
-		print("[USERCHAT] channel talk", e.user, e.channel, e.msg)
+		print("[USERCHAT] channel talk", e.login, e.channel, e.msg)
 	elseif e.e == "ChatJoin" then
 		self.channels[e.channel] = self.channels[e.channel] or {}
-		self.channels[e.channel][e.user] = true
+		self.channels[e.channel][e.login] = true
 		cprofile.pushEvent(string.format("e='Chat' se='Join' channel=%q login=%q name=%q ", e.channel, e.login, e.name))
-		print("[USERCHAT] channel join", e.user, e.channel)
+		print("[USERCHAT] channel join", e.login, e.channel)
 	elseif e.e == "ChatPart" then
 		self.channels[e.channel] = self.channels[e.channel] or {}
-		self.channels[e.channel][e.user] = nil
+		self.channels[e.channel][e.login] = nil
 		cprofile.pushEvent(string.format("e='Chat' se='Part' channel=%q login=%q name=%q ", e.channel, e.login, e.name))
-		print("[USERCHAT] channel part", e.user, e.channel)
+		print("[USERCHAT] channel part", e.login, e.channel)
 	end
 end
 
 function _M:joined(channel)
-	self.joined[channel] = true
+	self.cjoined[channel] = true
+	print("[ONLINE PROFILE] connected to channel", channel)
+end
+
+function _M:parted(channel)
+	self.cjoined[channel] = nil
+	print("[ONLINE PROFILE] parted from channel", channel)
 end
 
 function _M:reconnect()
 	-- Rejoin every channels
-	for chan, _ in pairs(self.joined) do
-		client:orderChatJoin{channel=chan}
+	print("[ONLINE PROFILE] reconnecting to channels")
+	for chan, _ in pairs(self.cjoined) do
+		print("[ONLINE PROFILE] reconnecting to channel", chan)
+		self.client:orderChatJoin{channel=chan}
 	end
 end
diff --git a/game/profile-thread/init.lua b/game/profile-thread/init.lua
index 7c8dc4bfbe93a4cd6b865cea45e98a11d25f2204..0b198ce508ad81bb07eb161f17b0bb1418dd5639 100644
--- a/game/profile-thread/init.lua
+++ b/game/profile-thread/init.lua
@@ -23,7 +23,7 @@ local Client = require "profile-thread.Client"
 local c = Client.new()
 
 function step_profile()
-	local ok, res = xpcall(function() return c:run() end, function(...) server:logError("[profile-thread-error:stacktrace] %s", debug.traceback(...)) end)
+	local ok, res = xpcall(function() return c:run() end, debug.traceback)
 	if not ok and res then
 		print("[PROFILE THREAD] error", res)
 		return false