Feche1320 Posted February 26, 2012 Share Posted February 26, 2012 I am recording keys that player press client-side, but when I send the table to server-side using 'triggerServerEvent', It seems that it doesn't send all data.. Here is an example: local pRecordingInfo = { startPosX, startPosY, startPosZ, startRotX, startRotY, startRotZ, pVeh = nil, vehModel = nil, pKey = {}, pKeyState = {}, vehHealth = {}, posUpdX = {}, posUpdY = {}, posUpdZ = {}, posUpdRotX = {}, posUpdRotY = {}, posUpdRotZ = {}, posUpdVelX = {}, posUpdVelY = {}, posUpdVelZ = {} } -- Put all the info on each table, etc triggerServerEvent("sendPressedKeys", g_Root, pRecordingInfo) -- Server side table = nil addEvent("sendPressedKeys", true) addEventHandler("sendPressedKeys", g_Root, funtion(info) table = info end ) outputChatBox(table.startPosX) -- Works good outputChatBox(table.posUpdX[1]) -- Gives me a nil value So, whats the problem? Thanks Link to comment
Kenix Posted February 26, 2012 Share Posted February 26, 2012 local pRecordingInfo = { startPosX, startPosY, startPosZ, startRotX, startRotY, startRotZ, pVeh = nil, vehModel = nil, pKey = {}, pKeyState = {}, vehHealth = {}, posUpdX = {}, posUpdY = {}, posUpdZ = {}, posUpdRotX = {}, posUpdRotY = {}, posUpdRotZ = {}, posUpdVelX = {}, posUpdVelY = {}, posUpdVelZ = {} } -- Put all the info on each table, etc triggerServerEvent("sendPressedKeys", g_Root, pRecordingInfo) -- Server side table = nil addEvent("sendPressedKeys", true) addEventHandler("sendPressedKeys", g_Root, function(info) table = info end ) outputChatBox(table.startPosX) -- Works good outputChatBox(table.posUpdX[1]) -- Gives me a nil value Fixed. addEvent("sendPressedKeys", true) addEventHandler("sendPressedKeys", g_Root, funcion(info) -- You use funcion, but need use function. table = info end ) So in your code syntax error , if you understand. Link to comment
Feche1320 Posted February 26, 2012 Author Share Posted February 26, 2012 Actually, I made that code here, that's why it had that typo.. This is the original code: addEventHandler("preparePlaybackForStart", g_Root, function(info) pRecordingInfo = info -- Here is where I set the information.. playbackSettings.gPed = createPed(264, pRecordingInfo.startPosX, pRecordingInfo.startPosY, pRecordingInfo.startPosZ) playbackSettings.gVeh = createVehicle(pRecordingInfo.vehModel, pRecordingInfo.startPosX, pRecordingInfo.startPosY, pRecordingInfo.startPosZ, pRecordingInfo.startRotX, pRecordingInfo.startRotY, pRecordingInfo.startRotZ) warpPedIntoVehicle(playbackSettings.gPed, playbackSettings.gVeh) createBlipAttachedTo(playbackSettings.gVeh, 0, 2.5, 255, 255, 0, 200) outputDebugString("[starting playback..]") playTimer = setTimer(startGhostPlayback, ACCURACY, 0) end ) Link to comment
Kenix Posted February 26, 2012 Share Posted February 26, 2012 You can write, what not work? /debugscript 3? Link to comment
Feche1320 Posted February 26, 2012 Author Share Posted February 26, 2012 (edited) outputChatBox(pRecordingInfo.posUpdX[1]) -- Gives me a nil value, it should give me a X coordinate. Edited February 26, 2012 by Guest Link to comment
Kenix Posted February 26, 2012 Share Posted February 26, 2012 You insert to table? table = { } table.posUpdX = { } table.posUpdX[1] = 123 print( table.posUpdX[1] ) -- 123 Updated. Example Link to comment
Feche1320 Posted February 26, 2012 Author Share Posted February 26, 2012 Yes. table.insert(pRecordingInfo.posUpdX, tmpX) Link to comment
Kenix Posted February 26, 2012 Share Posted February 26, 2012 Yes. table.insert(pRecordingInfo.posUpdX, tmpX) What return variable tmpX? Show full code please. Link to comment
Feche1320 Posted February 26, 2012 Author Share Posted February 26, 2012 Basicly, it's this: local tmpX, tmpY, tmpZ = getElementPosition(veh) table.insert(pRecordingInfo.posUpdX, tmpX) table.insert(pRecordingInfo.posUpdY, tmpY) table.insert(pRecordingInfo.posUpdZ, tmpZ) I get the vehicle position, and insert it to the table, after all that, I send the table to the server using 'triggerServerEvent'. Link to comment
Kenix Posted February 26, 2012 Share Posted February 26, 2012 Basicly, it's this: local tmpX, tmpY, tmpZ = getElementPosition(veh) table.insert(pRecordingInfo.posUpdX, tmpX) table.insert(pRecordingInfo.posUpdY, tmpY) table.insert(pRecordingInfo.posUpdZ, tmpZ) I get the vehicle position, and insert it to the table, after all that, I send the table to the server using 'triggerServerEvent'. You check returned value getElementPosition? Maybe variable veh is not element and function getElementPosition return nil. Link to comment
Feche1320 Posted February 26, 2012 Author Share Posted February 26, 2012 Yes, I did check it, client side values are ok, the problem is when I send it to server side.. Link to comment
Kenix Posted February 26, 2012 Share Posted February 26, 2012 So getElementPosition not return nil value right? You can show full code please Link to comment
Feche1320 Posted February 26, 2012 Author Share Posted February 26, 2012 Server: g_Root = getRootElement() ACCURACY = 200 --200ms POS_UPDATE = 2500 --2500ms playTimer = nil tmpPosUpdCount = 1 pRecordingInfo = {} playbackSettings = { gPed = nil, gVeh = nil, vehModel = nil, lastTick = nil } addEvent("preparePlaybackForStart", true) addEventHandler("preparePlaybackForStart", g_Root, function(info) pRecordingInfo = info playbackSettings.gPed = createPed(264, pRecordingInfo.startPosX, pRecordingInfo.startPosY, pRecordingInfo.startPosZ) playbackSettings.gVeh = createVehicle(pRecordingInfo.vehModel, pRecordingInfo.startPosX, pRecordingInfo.startPosY, pRecordingInfo.startPosZ, pRecordingInfo.startRotX, pRecordingInfo.startRotY, pRecordingInfo.startRotZ) warpPedIntoVehicle(playbackSettings.gPed, playbackSettings.gVeh) createBlipAttachedTo(playbackSettings.gVeh, 0, 2.5, 255, 255, 0, 200) outputDebugString("[starting playback..]") playTimer = setTimer(startGhostPlayback, ACCURACY, 0) end ) function startGhostPlayback() if pRecordingInfo.pKey[tmpPosUpdCount] then triggerClientEvent("setControlState", g_Root, playbackSettings.gPed, pRecordingInfo.pKey[tmpPosUpdCount], pRecordingInfo.pKeyState[tmpPosUpdCount]) if not playbackSettings.lastTick then playbackSettings.lastTick = getTickCount() end if getTickCount() - playbackSettings.lastTick > POS_UPDATE then setElementPosition(playbackSettings.gVeh, pRecordingInfo.posUpdX[tmpPosUpdCount], pRecordingInfo.posUpdY[tmpPosUpdCount], pRecordingInfo.posUpdZ[tmpPosUpdCount]) setElementRotation(playbackSettings.gVeh, pRecordingInfo.posUpdRotX[tmpPosUpdCount], pRecordingInfo.posUpdRotY[tmpPosUpdCount], pRecordingInfo.posUpdRotZ[tmpPosUpdCount]) setElementVelocity(playbackSettings.gVeh, pRecordingInfo.posUpdVelX[tmpPosUpdCount], pRecordingInfo.posUpdVelY[tmpPosUpdCount], pRecordingInfo.posUpdVelZ[tmpPosUpdCount]) setElementHealth(playbackSettings.gVeh, pRecordingInfo.vehHealth[tmpPosUpdCount]) playbackSettings.lastTick = getTickCount() end tmpPosUpdCount = tmpPosUpdCount + 1 else killTimer(playTimer) tmpPosUpdCount = 1 pRecordingInfo = {} destroyElement(playbackSettings.gPed) destroyElement(playbackSettings.gVeh) outputChatBox"Finished!" end end Client: g_Root = getRootElement() g_Me = getLocalPlayer() keysTimer = nil ACCURACY = 200 --200ms POS_UPDATE = 2500 --2500ms lastKeysChecked = {} keysState = {} posTickUpd = nil keyNames = { "special_control_up", "special_control_down", "special_control_right", "special_control_left", "vehicle_look_right", "vehicle_look_left", "handbrake", "sub_mission", "horn", "brake_reverse", "accelerate", "steer_back", "steer_forward", "vehicle_right", "vehicle_left", "vehicle_secondary_fire", "vehicle_fire" } -- 17 local pRecordingInfo = { startPosX, startPosY, startPosZ, startRotX, startRotY, startRotZ, pVeh = nil, vehModel = nil, pKey = {}, pKeyState = {}, vehHealth = {}, posUpdX = {}, posUpdY = {}, posUpdZ = {}, posUpdRotX = {}, posUpdRotY = {}, posUpdRotZ = {}, posUpdVelX = {}, posUpdVelY = {}, posUpdVelZ = {} } addEvent("startRecording", true) addEvent("setControlState", true) addEventHandler("startRecording", g_Root, function() --resetRecordInfo() pRecordingInfo.pVeh = getPedOccupiedVehicle(g_Me) pRecordingInfo.startPosX, pRecordingInfo.startPosY, pRecordingInfo.startPosZ = getElementPosition(pRecordingInfo.pVeh) pRecordingInfo.startRotX, pRecordingInfo.startRotY, pRecordingInfo.startRotZ = getElementRotation(pRecordingInfo.pVeh) pRecordingInfo.vehModel = getElementModel(pRecordingInfo.pVeh) keysTimer = setTimer(recordKeys, ACCURACY, 0) outputDebugString("[Recording started]") end ) addEventHandler("setControlState", g_Root, function(ped, key, state) if key == "continue" or state == "continue" or key == "nothing" or state == "nothing" then else setPedControlState(ped, key, state) end end ) addEventHandler("onClientPlayerWasted", g_Root, function() resetRecordInfo() outputDebugString("[Recording stopped]") end ) function recordKeys() local veh = getPedOccupiedVehicle(g_Me) if veh then -- Got the hunter if getElementModel(veh) == 425 then if isTimer(keysTimer) then killTimer(keysTimer) end posTickUpd = nil lastKeysChecked = {} outputDebugString("[Recording finished]") return end -- Record the keys for i, k in ipairs(keyNames) do local state = getControlState(k) if state then if not lastKeysChecked[k] then table.insert(pRecordingInfo.pKey, k) table.insert(pRecordingInfo.pKeyState, state) lastKeysChecked[k] = true outputDebugString("getControlState key: " ..k.. " state: true") keysState[i] = nil else table.insert(pRecordingInfo.pKey, "continue") table.insert(pRecordingInfo.pKeyState, "continue") outputDebugString("getControlState key: " ..k.. " state: continue") end else if not state then if lastKeysChecked[k] then table.insert(pRecordingInfo.pKey, k) table.insert(pRecordingInfo.pKeyState, false) outputDebugString("getControlState key: " ..k.. " state: false") lastKeysChecked[k] = false else keysState[i] = true end end end end if getPressedKeys() == 17 then table.insert(pRecordingInfo.pKey, "nothing") table.insert(pRecordingInfo.pKeyState, "nothing") outputDebugString("getControlState key: nothing state: nothing") end -- Position update if not posTickUpd then posTickUpd = getTickCount() end if getTickCount() - posTickUpd > POS_UPDATE then local tmpX, tmpY, tmpZ = getElementPosition(veh) table.insert(pRecordingInfo.posUpdX, tmpX) table.insert(pRecordingInfo.posUpdY, tmpY) table.insert(pRecordingInfo.posUpdZ, tmpZ) tmpX, tmpY, tmpZ = getElementRotation(veh) table.insert(pRecordingInfo.posUpdRotX, tmpX) table.insert(pRecordingInfo.posUpdRotY, tmpY) table.insert(pRecordingInfo.posUpdRotZ, tmpZ) tmpX, tmpY, tmpZ = getElementVelocity(veh) table.insert(pRecordingInfo.posUpdVelX, tmpX) table.insert(pRecordingInfo.posUpdVelY, tmpY) table.insert(pRecordingInfo.posUpdVelZ, tmpZ) table.insert(pRecordingInfo.vehHealth, getElementHealth(veh)) posTickUpd = getTickCount() outputDebugString("[Pos update]") end else --resetRecordInfo() outputDebugString("[Error while recording, aborting..]", 0, 255, 0, 0) end end function resetRecordInfo() if isTimer(keysTimer) then killTimer(keysTimer) end pRecordingInfo = { startPosX, startPosY, startPosZ, startRotX, startRotY, startRotZ, pVeh = nil, vehModel = nil, pKey = {}, pKeyState = {}, posUpdX = {}, posUpdY = {}, posUpdZ = {}, posUpdRotX = {}, posUpdRotY = {}, posUpdRotZ = {}, posUpdVelX = {}, posUpdVelY = {}, posUpdVelZ = {}, vehHealth = {} } posTickUpd = nil lastKeysChecked = {} end function getPressedKeys() local count = 0 for i = 1, #keysState do if keysState[i] then count = count + 1 end end return count end addCommandHandler("asd", function() triggerServerEvent("preparePlaybackForStart", g_Root, pRecordingInfo) end ) addCommandHandler("data", function() local cc = 1 local second = 2500 setTimer( function() outputChatBox("Second " ..second.. " X: " ..pRecordingInfo.posUpdX[cc].. "Y: " ..pRecordingInfo.posUpdY[cc].. "Z: " ..pRecordingInfo.posUpdZ[cc]) second = second + 2500 cc = cc + 1 end , 2500, 0) end ) Link to comment
Kenix Posted February 26, 2012 Share Posted February 26, 2012 Try addEvent("startRecording", true) addEvent("setControlState", true) g_Root = getRootElement() g_Me = getLocalPlayer() keysTimer = nil ACCURACY = 200 --200ms POS_UPDATE = 2500 --2500ms lastKeysChecked = {} keysState = {} posTickUpd = nil keyNames = { "special_control_up", "special_control_down", "special_control_right", "special_control_left", "vehicle_look_right", "vehicle_look_left", "handbrake", "sub_mission", "horn", "brake_reverse", "accelerate", "steer_back", "steer_forward", "vehicle_right", "vehicle_left", "vehicle_secondary_fire", "vehicle_fire" } -- 17 local pRecordingInfo = { startPosX, startPosY, startPosZ, startRotX, startRotY, startRotZ, pVeh = nil, vehModel = nil, pKey = {}, pKeyState = {}, vehHealth = {}, posUpdX = {}, posUpdY = {}, posUpdZ = {}, posUpdRotX = {}, posUpdRotY = {}, posUpdRotZ = {}, posUpdVelX = {}, posUpdVelY = {}, posUpdVelZ = {} } function recordKeys() local veh = getPedOccupiedVehicle(g_Me) if veh then -- Got the hunter if getElementModel(veh) == 425 then if isTimer(keysTimer) then killTimer(keysTimer) end posTickUpd = nil lastKeysChecked = {} outputDebugString("[Recording finished]") return end -- Record the keys for i, k in ipairs(keyNames) do local state = getControlState(k) if state then if not lastKeysChecked[k] then table.insert(pRecordingInfo.pKey, k) table.insert(pRecordingInfo.pKeyState, state) lastKeysChecked[k] = true outputDebugString("getControlState key: " ..k.. " state: true") keysState = nil else table.insert(pRecordingInfo.pKey, "continue") table.insert(pRecordingInfo.pKeyState, "continue") outputDebugString("getControlState key: " ..k.. " state: continue") end else if not state then if lastKeysChecked[k] then table.insert(pRecordingInfo.pKey, k) table.insert(pRecordingInfo.pKeyState, false) outputDebugString("getControlState key: " ..k.. " state: false") lastKeysChecked[k] = false else keysState = true end end end end if getPressedKeys() == 17 then table.insert(pRecordingInfo.pKey, "nothing") table.insert(pRecordingInfo.pKeyState, "nothing") outputDebugString("getControlState key: nothing state: nothing") end -- Position update if not posTickUpd then posTickUpd = getTickCount() end if getTickCount() - posTickUpd > POS_UPDATE then local tmpX, tmpY, tmpZ = getElementPosition(veh) table.insert(pRecordingInfo.posUpdX, tmpX) table.insert(pRecordingInfo.posUpdY, tmpY) table.insert(pRecordingInfo.posUpdZ, tmpZ) tmpX, tmpY, tmpZ = getElementRotation(veh) table.insert(pRecordingInfo.posUpdRotX, tmpX) table.insert(pRecordingInfo.posUpdRotY, tmpY) table.insert(pRecordingInfo.posUpdRotZ, tmpZ) tmpX, tmpY, tmpZ = getElementVelocity(veh) table.insert(pRecordingInfo.posUpdVelX, tmpX) table.insert(pRecordingInfo.posUpdVelY, tmpY) table.insert(pRecordingInfo.posUpdVelZ, tmpZ) table.insert(pRecordingInfo.vehHealth, getElementHealth(veh)) posTickUpd = getTickCount() outputDebugString("[Pos update]") end else --resetRecordInfo() outputDebugString("[Error while recording, aborting..]", 0, 255, 0, 0) end end function resetRecordInfo() if isTimer(keysTimer) then killTimer(keysTimer) end pRecordingInfo = { startPosX, startPosY, startPosZ, startRotX, startRotY, startRotZ, pVeh = nil, vehModel = nil, pKey = {}, pKeyState = {}, posUpdX = {}, posUpdY = {}, posUpdZ = {}, posUpdRotX = {}, posUpdRotY = {}, posUpdRotZ = {}, posUpdVelX = {}, posUpdVelY = {}, posUpdVelZ = {}, vehHealth = {} } posTickUpd = nil lastKeysChecked = {} end function getPressedKeys() local count = 0 for i = 1, #keysState do if keysState then count = count + 1 end end return count end addEventHandler("startRecording", g_Root, function() --resetRecordInfo() pRecordingInfo.pVeh = getPedOccupiedVehicle(g_Me) pRecordingInfo.startPosX, pRecordingInfo.startPosY, pRecordingInfo.startPosZ = getElementPosition(pRecordingInfo.pVeh) pRecordingInfo.startRotX, pRecordingInfo.startRotY, pRecordingInfo.startRotZ = getElementRotation(pRecordingInfo.pVeh) pRecordingInfo.vehModel = getElementModel(pRecordingInfo.pVeh) keysTimer = setTimer(recordKeys, ACCURACY, 0) outputDebugString("[Recording started]") end ) addEventHandler("setControlState", g_Root, function(ped, key, state) if key == "continue" or state == "continue" or key == "nothing" or state == "nothing" then else setPedControlState(ped, key, state) end end ) addEventHandler("onClientPlayerWasted", g_Root, function() resetRecordInfo() outputDebugString("[Recording stopped]") end ) addCommandHandler("asd", function() triggerServerEvent("preparePlaybackForStart", g_Root, pRecordingInfo) end ) addCommandHandler("data", function() local cc = 1 local second = 2500 setTimer( function() outputChatBox("Second " ..second.. " X: " ..pRecordingInfo.posUpdX[cc].. "Y: " ..pRecordingInfo.posUpdY[cc].. "Z: " ..pRecordingInfo.posUpdZ[cc]) second = second + 2500 cc = cc + 1 end , 2500, 0) end ) Rules: Events Variables functions event handlers The order is important. Otherwise it will not work. Link to comment
Feche1320 Posted February 26, 2012 Author Share Posted February 26, 2012 Nope, still not working. Link to comment
Kenix Posted February 26, 2012 Share Posted February 26, 2012 (edited) Can you debug full, function recordKeys? return values in functions,variables,... Edited February 26, 2012 by Guest Link to comment
Feche1320 Posted February 26, 2012 Author Share Posted February 26, 2012 I already did a test.. client-side the table is OK, when I send it to the server is where the problem comes... I think that it's a MTA bug or something, but not the script. Link to comment
Kenix Posted February 26, 2012 Share Posted February 26, 2012 addEventHandler("preparePlaybackForStart", g_Root, function(info) for i,v in pairs( info ) do outputChatBox( 'index'..tostring( i )..'value'..tostring( v ) ) end --... Try it. And we find out whether it contains anything or not. Link to comment
Feche1320 Posted February 26, 2012 Author Share Posted February 26, 2012 index startRotZ value 81.996459960938 index vehModel value 522 index startPosZ value 13 index startPosY value -1675.5 index vehHealth value table: 029B50C0 index posUpdRotZ value table: 029B65E8 index posUpdZ value table: 029BA560 index pKeyState value table: 03CB5CB8 index posUpdVelX value table: 03CC2BB0 index posUpdRotY value table: 03CC1770 index startRotY value 0 index posUpdX value table: 03CC0230 index startRotX value 0 index posUpdY value table: 03CA00C8 index posUpdRotX value table: 03CAA9B8 index startPosX value 2495.7998046875 index posUpdVelZ value table: 03CA71D8 index posUpdVelY value table: 03CA53A8 index pKey value table: 029BBA38 index pVeh value userdata: 00000D6D Link to comment
Kenix Posted February 26, 2012 Share Posted February 26, 2012 addEvent("preparePlaybackForStart", true) g_Root = getRootElement() ACCURACY = 200 --200ms POS_UPDATE = 2500 --2500ms local playTimer tmpPosUpdCount = 1 pRecordingInfo = {} local uTimer playbackSettings = { gPed = nil, gVeh = nil, vehModel = nil, lastTick = nil } function startGhostPlayback() if pRecordingInfo.pKey[tmpPosUpdCount] then triggerClientEvent("setControlState", g_Root, playbackSettings.gPed, pRecordingInfo.pKey[tmpPosUpdCount], pRecordingInfo.pKeyState[tmpPosUpdCount]) if not playbackSettings.lastTick then playbackSettings.lastTick = getTickCount() end if getTickCount() - playbackSettings.lastTick > POS_UPDATE then setElementPosition(playbackSettings.gVeh, pRecordingInfo.posUpdX[tmpPosUpdCount], pRecordingInfo.posUpdY[tmpPosUpdCount], pRecordingInfo.posUpdZ[tmpPosUpdCount]) setElementRotation(playbackSettings.gVeh, pRecordingInfo.posUpdRotX[tmpPosUpdCount], pRecordingInfo.posUpdRotY[tmpPosUpdCount], pRecordingInfo.posUpdRotZ[tmpPosUpdCount]) setElementVelocity(playbackSettings.gVeh, pRecordingInfo.posUpdVelX[tmpPosUpdCount], pRecordingInfo.posUpdVelY[tmpPosUpdCount], pRecordingInfo.posUpdVelZ[tmpPosUpdCount]) setElementHealth(playbackSettings.gVeh, pRecordingInfo.vehHealth[tmpPosUpdCount]) playbackSettings.lastTick = getTickCount() end tmpPosUpdCount = tmpPosUpdCount + 1 else killTimer(playTimer) tmpPosUpdCount = 1 pRecordingInfo = {} destroyElement(playbackSettings.gPed) destroyElement(playbackSettings.gVeh) outputChatBox"Finished!" end end addEventHandler("preparePlaybackForStart", g_Root, function(info) pRecordingInfo = info playbackSettings.gPed = createPed( 264, tonumber( pRecordingInfo.startPosX ),tonumber( pRecordingInfo.startPosY ), tonumber( pRecordingInfo.startPosZ ) ) outputChatBox( 'ped--> '..tostring( playbackSettings.gPed ) ) playbackSettings.gVeh = createVehicle( tonumber( pRecordingInfo.vehModel ),tonumber( pRecordingInfo.startPosX ), tonumber( pRecordingInfo.startPosY ),tonumber( pRecordingInfo.startPosZ ),tonumber( pRecordingInfo.startRotX ), tonumber( pRecordingInfo.startRotY ),tonumber( pRecordingInfo.startRotZ ) ) outputChatBox( 'veh--> '..tostring( playbackSettings.gVeh ) ) uTimer = setTimer( warpPedIntoVehicle,1000,1,playbackSettings.gPed, playbackSettings.gVeh ) outputChatBox( 'blip--> '..tostring( createBlipAttachedTo( playbackSettings.gVeh, 0, 2.5, 255, 255, 0, 200 ) ) ) outputDebugString ("[starting playback..]" ) playTimer = setTimer( startGhostPlayback, ACCURACY, 0 ) end ) Updated. Try debug it. Link to comment
Feche1320 Posted February 26, 2012 Author Share Posted February 26, 2012 The part that you debugged works fine. Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now