Add prototype for Mercury Sync plugin

This commit is contained in:
Lewin Kelly 2023-10-11 09:47:18 +01:00
parent a469089a6e
commit 45fc10999f
15 changed files with 9949 additions and 457 deletions

View File

@ -1,2 +1,3 @@
# melt
Roblox UI library built for backwards compatibility
Backwards-compatible tooling for Roblox development

164
Sync/Plugin/Plugin.lua Normal file
View File

@ -0,0 +1,164 @@
local plugin = PluginManager():CreatePlugin()
local initiated = false
local HttpService = game:GetService "HttpService"
HttpService.HttpEnabled = true
local function initiate()
if initiated then
return
end
initiated = true
print "Initiating network server for Mercury Sync."
print "Hosting servers is not possible after opening Mercury Sync! Please restart Studio to host servers again."
game:GetService("NetworkServer"):Start()
end
local toolbar = plugin:CreateToolbar "Mercury Sync"
local button = toolbar:CreateButton(
"", -- The text next to the icon. Leave this blank if the icon is sufficient.
"Sync!", -- hover text
"icon.png" -- The icon file's name. Make sure you change it to your own icon file's name!
)
local Fusion = LoadLibrary "RbxFusion"
local New = Fusion.New
local Children = Fusion.Children
local Value = Fusion.Value
local Spring = Fusion.Spring
local peek = Fusion.peek
local g
local notifications = {}
local WIDTH = 250
-- the gui is removed when there are no notifications,
-- to prevent remaining in StarterGui
local function gui()
if not g then
g = New "ScreenGui" {
Name = "Mercury Sync",
Parent = game.StarterGui,
[Children] = New "Frame" {
Name = "Notifications",
BackgroundColor3 = Color3.new(0, 0, 0),
BackgroundTransparency = 1,
Position = UDim2.new(0, 0, 0, 0),
Size = UDim2.new(0, WIDTH, 1, 0),
},
}
local conn, destroyed
conn = g.Notifications.DescendantRemoving:connect(function()
wait(1)
if not destroyed and #g.Notifications:GetChildren() == 0 then
g:Destroy()
g = nil
notifications = {}
destroyed = true
conn:disconnect()
end
end)
end
return g
end
local function notifyCount()
local count = 0
for _, _ in pairs(notifications) do
count = count + 1
end
return count
end
local idCount = 0
local function notify(text)
local startCount = notifyCount()
local position = Value(UDim2.new(0, -WIDTH, 0, 60 * (startCount + 1) - 50))
local transparency = Value(0)
idCount = idCount + 1
local id = idCount
local t = New "Frame" {
Name = "Notification",
Parent = gui().Notifications,
BackgroundColor3 = Color3.new(),
BackgroundTransparency = Spring(transparency, 15),
BorderSizePixel = 0,
Position = Spring(position, 15),
Size = UDim2.new(1, 0, 0, 50),
[Children] = {
New "ImageLabel" {
Image = "rbxasset://../../../Plugins/TestPlugin/icon2.png",
BackgroundTransparency = 1,
Position = UDim2.new(0, 5, 0, 5),
Size = UDim2.new(0, 40, 0, 40),
},
New "TextLabel" {
Position = UDim2.new(0, 50, 0, 0),
Size = UDim2.new(1, -60, 1, 0),
BackgroundTransparency = 1,
Text = text,
TextWrapped = true,
TextColor3 = Color3.new(1, 1, 1),
Font = Enum.Font.SourceSans,
FontSize = Enum.FontSize.Size18,
TextXAlignment = Enum.TextXAlignment.Center,
TextYAlignment = Enum.TextYAlignment.Center,
},
},
}
local tbl = {
obj = t,
pos = position,
}
notifications[id] = tbl
position:set(peek(position) + UDim2.new(0, WIDTH, 0, 0))
transparency:set(0.5)
wait(3)
position:set(UDim2.new(0, 0, 0, -60))
transparency:set(1)
notifications[id] = nil
for _, v in pairs(notifications) do
if peek(v.pos).Y.Offset > peek(position).Y.Offset then
v.pos:set(peek(v.pos) - UDim2.new(0, 0, 0, 60))
end
end
wait(1)
t:Destroy()
end
local debounce
button.Click:connect(function()
if debounce then
return
end
debounce = true
initiate()
local ok, res = ypcall(function()
return HttpService:GetAsync "http://localhost:2013/"
end)
if ok then
notify("Synced: " .. res)
else
notify "Failed to sync! Is Mercury Sync Server running?"
end
debounce = false
end)

BIN
Sync/Plugin/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
Sync/Plugin/icon2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

169
Sync/Server/.gitignore vendored Normal file
View File

@ -0,0 +1,169 @@
# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
# Logs
logs
_.log
npm-debug.log_
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
.pnpm-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
# Runtime data
pids
_.pid
_.seed
\*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
\*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
\*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
\*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp and cache directory
.temp
.cache
# Docusaurus cache and generated files
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.\*

BIN
Sync/Server/bun.lockb Normal file

Binary file not shown.

5
Sync/Server/index.ts Normal file
View File

@ -0,0 +1,5 @@
import { Elysia } from "elysia"
const app = new Elysia().get("/", () => "Hello World!").listen(2013)
console.log(`Serving at http://${app.server?.hostname}:${app.server?.port}`)

14
Sync/Server/package.json Normal file
View File

@ -0,0 +1,14 @@
{
"name": "sync",
"module": "index.ts",
"type": "module",
"devDependencies": {
"bun-types": "latest"
},
"peerDependencies": {
"typescript": "^5.0.0"
},
"dependencies": {
"elysia": "^0.6.12"
}
}

21
Sync/Server/tsconfig.json Normal file
View File

@ -0,0 +1,21 @@
{
"compilerOptions": {
"lib": ["ESNext"],
"module": "esnext",
"target": "esnext",
"moduleResolution": "bundler",
"moduleDetection": "force",
"allowImportingTsExtensions": true,
"strict": true,
"downlevelIteration": true,
"skipLibCheck": true,
"jsx": "preserve",
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"allowJs": true,
"noEmit": true,
"types": [
"bun-types" // add Bun global
]
}
}

269
melt.yml
View File

@ -1,269 +0,0 @@
globals:
Accoutrement:
any: true
Animation:
any: true
AnimationController:
any: true
AnimationTrack:
any: true
ArcHandles:
any: true
Backpack:
any: true
BackpackItem:
any: true
BillboardGui:
any: true
BindableEvent:
any: true
BindableFunction:
any: true
BlockMesh:
any: true
BodyAngularVelocityBodyColors:
any: true
BodyForce:
any: true
BodyGyro:
any: true
BodyPosition:
any: true
BodyThrust:
any: true
BodyVelocity:
any: true
BoolValue:
any: true
BrickColorValue:
any: true
CFrameValue:
any: true
Camera:
any: true
CharacterMesh:
any: true
ClickDetector:
any: true
Clothing:
any: true
Color3Value:
any: true
Configuration:
any: true
CornerWedgePart:
any: true
CustomEvent:
any: true
CustomEventReceiver:
any: true
CylinderMesh:
any: true
DataModel:
any: true
Debris:
any: true
Decal:
any: true
Dialog:
any: true
DialogChoice:
any: true
DoubleConstrainedValue:
any: true
Explosion:
any: true
Feature:
any: true
FileMesh:
any: true
Fire:
any: true
Flag:
any: true
FlagStand:
any: true
FloorWire:
any: true
ForceField:
any: true
Frame:
any: true
Glue:
any: true
Handles:
any: true
Hat:
any: true
Hole:
any: true
HopperBin:
any: true
Humanoid:
any: true
ImageButton:
any: true
ImageLabel:
any: true
IntConstrainedValue:
any: true
IntValue:
any: true
JointInstance:
any: true
Keyframe:
any: true
Lighting:
any: true
LocalBackpack:
any: true
LocalScript:
any: true
Message:
any: true
Model:
any: true
ModuleScript:
any: true
Motor:
any: true
MotorFeature:
any: true
Mouse:
any: true
NetworkClient:
any: true
NetworkReplicator:
any: true
NetworkServer:
any: true
NumberValue:
any: true
ObjectValue:
any: true
Pants:
any: true
Part:
any: true
Platform:
any: true
Player:
any: true
PlayerGui:
any: true
Players:
any: true
Plugin:
any: true
PluginManager:
any: true
PluginMouse:
any: true
PointLight:
any: true
Pose:
any: true
ProfilingItem:
any: true
RayValue:
any: true
RemoteEvent:
any: true
RemoteFunction:
any: true
ReplicatedStorage:
any: true
RocketPropulsion:
any: true
RotateP:
any: true
RotateV:
any: true
ScreenGui:
any: true
Script:
any: true
ScriptContext:
any: true
Seat:
any: true
Selection:
any: true
SelectionBox:
any: true
SelectionPartLasso:
any: true
SelectionPointLasso:
any: true
Shirt:
any: true
ShirtGraphic:
any: true
SkateboardPlatform:
any: true
Skin:
any: true
Sky:
any: true
Smoke:
any: true
Snap:
any: true
Sound:
any: true
Sparkles:
any: true
SpawnLocation:
any: true
SpecialMesh:
any: true
SpotLight:
any: true
StarterGear:
any: true
StatsItem:
any: true
Status:
any: true
StringValue:
any: true
StudioTool:
any: true
SurfaceGui:
any: true
SurfaceSelection:
any: true
TaskScheduler:
any: true
Team:
any: true
Terrain:
any: true
TerrainRegion:
any: true
TextBox:
any: true
TextButton:
any: true
TextLabel:
any: true
Texture:
any: true
TextureTrail:
any: true
Tool:
any: true
TrussPart:
any: true
Vector3Value:
any: true
VehicleSeat:
any: true
VelocityMotor:
any: true
WedgePart:
any: true
Weld:
any: true

9572
mercury.yml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1 @@
std = "roblox+melt"
[lints]
global_usage = "allow"
std = "mercury"

View File

@ -1,19 +0,0 @@
local ReplicatedStorage = game:GetService "ReplicatedStorage"
require(ReplicatedStorage.melt)()
local localPlayer = game:GetService("Players").LocalPlayer
ScreenGui {
Parent = localPlayer:WaitForChild "PlayerGui",
Frame {
Size = UDim2.fromScale(0.5, 0.5),
TextLabel {
Position = UDim2.fromScale(0.5, 0.5),
Text = "Hello world!",
TextSize = 24,
BackgroundTransparency = 1,
},
},
}

View File

@ -1,163 +0,0 @@
local instances = {
"Accoutrement",
"Animation",
"AnimationController",
"AnimationTrack",
"ArcHandles",
"Backpack",
"BackpackItem",
"BillboardGui",
"BindableEvent",
"BindableFunction",
"BlockMesh",
"BodyAngularVelocityBodyColors",
"BodyForce",
"BodyGyro",
"BodyPosition",
"BodyThrust",
"BodyVelocity",
"BoolValue",
"BrickColorValue",
"CFrameValue",
"Camera",
"CharacterMesh",
"ClickDetector",
"Clothing",
"Color3Value",
"Configuration",
"CornerWedgePart",
"CustomEvent",
"CustomEventReceiver",
"CylinderMesh",
"Decal",
"Dialog",
"DialogChoice",
"DoubleConstrainedValue",
"Explosion",
"Feature",
"FileMesh",
"Fire",
"Flag",
"FlagStand",
"FloorWire",
"ForceField",
"Frame",
"Glue",
"Handles",
"Hat",
"Hole",
"HopperBin",
"Humanoid",
"ImageButton",
"ImageLabel",
"IntConstrainedValue",
"IntValue",
"JointInstance",
"Keyframe",
"LocalBackpack",
"LocalScript",
"Message",
"Model",
"ModuleScript",
"Motor",
"MotorFeature",
"Mouse",
"NetworkClient",
"NetworkReplicator",
"NetworkServer",
"NumberValue",
"ObjectValue",
"Pants",
"Part",
"Platform",
"Plugin",
"PluginManager",
"PluginMouse",
"PointLight",
"Pose",
"ProfilingItem",
"RayValue",
"RemoteEvent",
"RemoteFunction",
"ReplicatedStorage",
"RocketPropulsion",
"RotateP",
"RotateV",
"ScreenGui",
"Script",
"ScriptContext",
"Seat",
"Selection",
"SelectionBox",
"SelectionPartLasso",
"SelectionPointLasso",
"Shirt",
"ShirtGraphic",
"SkateboardPlatform",
"Skin",
"Sky",
"Smoke",
"Snap",
"Sound",
"Sparkles",
"SpawnLocation",
"SpecialMesh",
"SpotLight",
"StarterGear",
"StatsItem",
"Status",
"StringValue",
"StudioTool",
"SurfaceGui",
"SurfaceSelection",
"TaskScheduler",
"Team",
"Terrain",
"TerrainRegion",
"TextBox",
"TextButton",
"TextLabel",
"Texture",
"TextureTrail",
"Tool",
"TrussPart",
"Vector3Value",
"VehicleSeat",
"VelocityMotor",
"WedgePart",
"Weld",
}
local globals = {}
for _, objectType in ipairs(instances) do
globals[objectType] = function(dat)
local obj = Instance.new(objectType)
local parent
for k, v in pairs(dat) do
if type(k) == "string" then
if k == "Parent" then
parent = v
else
obj[k] = v
end
elseif type(k) == "number" and type(v) == "userdata" then
v.Parent = obj
end
end
obj.Parent = parent
return obj
end
end
return function()
-- Vomit everything into the global scope
local env = getfenv(0)
for k, v in globals do
env[k] = v
end
setfenv(0, env)
end

View File

@ -1,4 +1,4 @@
column_width = 120
column_width = 80
line_endings = "Unix"
indent_type = "Tabs"
indent_width = 4