Roblox/Minecraft server link
From ihaveahax's Site
< Roblox
Jump to navigationJump to search
I once created a very simple link between a Roblox and Minecraft Java game server. It only reported positions from the Minecraft world to Roblox. Later I made something that could return chunks from the world but the code for that is buried somewhere.
The Minecraft side uses the CommandHelper plugin, which uses the MethodScript language.
This does NOT work on a live Roblox server since it expects there to be little to no latency (it doesn't deal with this well). And Roblox may not like the high volume of HTTP requests going out. It also does not filter Minecraft usernames. Filtering them wouldn't work that well anyway.
CommandHelper main.ms
<!
strict;
author: Ian Burgwin (ihaveahax)
created: 2020-03-17
description: Return player positions. (Eventually will handle Roblox player positions.)
>
httpd_listen(29295) #-- 0x726F (ro)
bind('http_request', null, null, @event) {
modify_event('code', 200);
httpd_set_header('Content-Type', 'application/json');
array @positions = array();
array @smaller_ploc;
array @c; # current position
foreach(all_players(), @player) {
@c = location_shift(ploc(@player), 'UP', 1);
@smaller_ploc = array('x': @c['x'], 'y': @c['y'], 'z': @c['z'], 'pitch': @c['pitch'], 'yaw': @c['yaw']);
@positions[@player] = @smaller_ploc;
}
modify_event('body', json_encode(@positions));
}
Roblox object hierarchy
- Workspace
- MCCurrentPlayers (Folder)
- ServerStorage
- MCServerLink (Folder)
- HttpHandler (Script)
- PlayerHandler (Script)
- MakeRequest (BindableEvent)
- PlayerAdded (BindableEvent)
- PlayerMove (BindableEvent)
- PlayerRemoving (BindableEvent)
- Base (Model)
- MCServerLink (Folder)
ServerScriptService.MCServerLink.HttpHandler
Makes a request to the server roughly every 1/6th of a second, making up to 360 requests per minute.
local HttpService = game:GetService('HttpService')
local ServerStorage = game:GetService('ServerStorage')
local Storage = ServerStorage.MCServerLink
local MakeRequest = Storage.MakeRequest
local PlayerAdded = Storage.PlayerAdded
local PlayerRemoving = Storage.PlayerRemoving
local PlayerMove = Storage.PlayerMove
local Url = 'http://localhost:29295'
-- key is the username, value is always true
-- this loses order, but is faster than an ordered table
local CurrentPlayers = {}
local function HandleMakeRequest()
print('Requesting...')
local Positions = HttpService:JSONDecode(HttpService:GetAsync(Url))
print('Got data')
for Username, _ in pairs(CurrentPlayers) do
if not Positions[Username] then
print('Player removed: '..Username)
PlayerRemoving:Fire(Username)
end
end
for Username, PositionData in pairs(Positions) do
local Position = Vector3.new(PositionData['x'], PositionData['y'], PositionData['z'])
local Orientation = Vector3.new(0, PositionData['yaw'], -PositionData['pitch'])
if not CurrentPlayers[Username] then
print('Player added: '..Username)
PlayerAdded:Fire(Username, Position, Orientation)
CurrentPlayers[Username] = true
else
print('Player moved: '..Username)
PlayerMove:Fire(Username, Position, Orientation)
end
end
end
MakeRequest.Event:Connect(HandleMakeRequest)
print('HttpHandler ready')
while wait(1/6) do
MakeRequest:Fire()
end
ServerScriptService.MCServerLink.PlayerHandler
local HttpService = game:GetService('HttpService')
local ServerStorage = game:GetService('ServerStorage')
local TextService = game:GetService('TextService')
local TweenService = game:GetService('TweenService')
local Storage = ServerStorage.MCServerLink
local PlayerAdded = Storage.PlayerAdded
local PlayerRemoving = Storage.PlayerRemoving
local PlayerMove = Storage.PlayerMove
local BaseModel = Storage.Base
local CurrentPlayersFolder = workspace.MCCurrentPlayers
local TInfo = TweenInfo.new(1/6, Enum.EasingStyle.Linear, Enum.EasingDirection.In, 0, false)
local function GetPlayerModel(Username)
local Model = CurrentPlayersFolder:FindFirstChild(Username)
if not Model then
Model = BaseModel:Clone()
Model.Name = Username
Model.Head.NameGui.NameLabel.Text = Username
-- not depending on the label here
local TextSize = TextService:GetTextSize(Username, 100, Enum.Font.Gotham, Vector2.new(2000, 100))
Model.Head.NameGui.Background.Size = UDim2.new((TextSize.X / 2000) + 0.01, 0, 1, 0)
Model.Parent = CurrentPlayersFolder
end
return Model
end
local function MovePlayer(Model, Position, Orientation)
local CF = CFrame.Angles(0, -math.rad(Orientation.Y + 180), 0)
CF = CF:ToWorldSpace(CFrame.new())
local Goal = {['CFrame'] = CF + (Position * 4)}
local Tween = TweenService:Create(Model.PrimaryPart, TInfo, Goal)
Tween:Play()
end
local function HandlePlayerChange(Username, Position, Orientation)
local Model = GetPlayerModel(Username)
MovePlayer(Model, Position, Orientation)
end
local function HandlePlayerRemove(Username)
local Model = CurrentPlayersFolder:FindFirstChild(Username)
if Model then
Model:Destroy()
end
end
PlayerAdded.Event:Connect(HandlePlayerChange)
PlayerMove.Event:Connect(HandlePlayerChange)
PlayerRemoving.Event:Connect(HandlePlayerRemove)