mirror of
https://github.com/rojo-rbx/rojo.git
synced 2026-04-20 20:55:50 +00:00
Compare commits
13 Commits
v7.4.0-rc1
...
v7.4.0-rc3
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41994ec82e | ||
|
|
cd14ea7c62 | ||
|
|
9f13bca6b8 | ||
|
|
f4252c3e97 | ||
|
|
6598867d3d | ||
|
|
f39e040a0d | ||
|
|
a3d140269b | ||
|
|
feac29ea40 | ||
|
|
834c8cdbca | ||
|
|
d441fbdf91 | ||
|
|
e897f524dc | ||
|
|
1caf9446d8 | ||
|
|
bfd2c885db |
20
CHANGELOG.md
20
CHANGELOG.md
@@ -2,6 +2,26 @@
|
||||
|
||||
## Unreleased Changes
|
||||
|
||||
## [7.4.0-rc3] - October 25, 2023
|
||||
* Changed `sourcemap --watch` to only generate the sourcemap when it's necessary ([#800])
|
||||
* Switched script source property getter and setter to `ScriptEditorService` methods ([#801])
|
||||
|
||||
This ensures that the script editor reflects any changes Rojo makes to a script while it is open in the script editor.
|
||||
|
||||
* Fixed issues when handling `SecurityCapabilities` values ([#803], [#807])
|
||||
* Fixed Rojo plugin erroring out when attempting to sync attributes with invalid names ([#809])
|
||||
|
||||
[#800]: https://github.com/rojo-rbx/rojo/pull/800
|
||||
[#801]: https://github.com/rojo-rbx/rojo/pull/801
|
||||
[#803]: https://github.com/rojo-rbx/rojo/pull/803
|
||||
[#807]: https://github.com/rojo-rbx/rojo/pull/807
|
||||
[#809]: https://github.com/rojo-rbx/rojo/pull/809
|
||||
|
||||
## [7.4.0-rc2] - October 3, 2023
|
||||
* Fixed bug with parsing version for plugin validation ([#797])
|
||||
|
||||
[#797]: https://github.com/rojo-rbx/rojo/pull/797
|
||||
|
||||
## [7.4.0-rc1] - October 3, 2023
|
||||
### Additions
|
||||
#### Project format
|
||||
|
||||
10
Cargo.lock
generated
10
Cargo.lock
generated
@@ -1586,9 +1586,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rbx_binary"
|
||||
version = "0.7.2"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10942950a57c939e540a2f977ba55e9140007d7e96c532d455502c290fdf710d"
|
||||
checksum = "ad50c13afe91296dad6508ea7e29f4b665fa56cb664ad01eaf8fdbd3da69d5e1"
|
||||
dependencies = [
|
||||
"log",
|
||||
"lz4",
|
||||
@@ -1831,7 +1831,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rojo"
|
||||
version = "7.4.0-rc1"
|
||||
version = "7.4.0-rc3"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"backtrace",
|
||||
@@ -1908,9 +1908,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.15"
|
||||
version = "0.38.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2f9da0cbd88f9f09e7814e388301c8414c51c62aa6ce1e4b5c551d49d96e531"
|
||||
checksum = "67ce50cb2e16c2903e30d1cbccfd8387a74b9d4c938b6a4c5ec6cc7556f7a8a0"
|
||||
dependencies = [
|
||||
"bitflags 2.4.0",
|
||||
"errno",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "rojo"
|
||||
version = "7.4.0-rc1"
|
||||
version = "7.4.0-rc3"
|
||||
rust-version = "1.70.0"
|
||||
authors = ["Lucien Greathouse <me@lpghatguy.com>"]
|
||||
description = "Enables professional-grade development tools for Roblox developers"
|
||||
@@ -49,7 +49,7 @@ memofs = { version = "0.2.0", path = "crates/memofs" }
|
||||
# rbx_reflection_database = { path = "../rbx-dom/rbx_reflection_database" }
|
||||
# rbx_xml = { path = "../rbx-dom/rbx_xml" }
|
||||
|
||||
rbx_binary = "0.7.2"
|
||||
rbx_binary = "0.7.3"
|
||||
rbx_dom_weak = "2.6.0"
|
||||
rbx_reflection = "4.4.0"
|
||||
rbx_reflection_database = "0.2.8"
|
||||
|
||||
2
build.rs
2
build.rs
@@ -46,7 +46,7 @@ fn main() -> Result<(), anyhow::Error> {
|
||||
|
||||
let our_version = Version::parse(env::var_os("CARGO_PKG_VERSION").unwrap().to_str().unwrap())?;
|
||||
let plugin_version =
|
||||
Version::parse(fs::read_to_string(&plugin_root.join("Version.txt"))?.trim())?;
|
||||
Version::parse(fs::read_to_string(plugin_root.join("Version.txt"))?.trim())?;
|
||||
|
||||
assert!(
|
||||
our_version.major == plugin_version.major,
|
||||
|
||||
@@ -1 +1 @@
|
||||
7.4.0-rc1
|
||||
7.4.0-rc3
|
||||
@@ -412,15 +412,6 @@ types = {
|
||||
end,
|
||||
},
|
||||
|
||||
SecurityCapabilities = {
|
||||
fromPod = function(_pod)
|
||||
error("SecurityCapabilities is not implemented")
|
||||
end,
|
||||
toPod = function(_roblox)
|
||||
error("SecurityCapabilities is not implemented")
|
||||
end,
|
||||
},
|
||||
|
||||
SharedString = {
|
||||
fromPod = function(_pod)
|
||||
error("SharedString is not supported")
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
local CollectionService = game:GetService("CollectionService")
|
||||
local ScriptEditorService = game:GetService("ScriptEditorService")
|
||||
|
||||
--- A list of `Enum.Material` values that are used for Terrain.MaterialColors
|
||||
local TERRAIN_MATERIAL_COLORS = {
|
||||
@@ -36,9 +37,24 @@ return {
|
||||
end,
|
||||
write = function(instance, _, value)
|
||||
local existing = instance:GetAttributes()
|
||||
local didAllWritesSucceed = true
|
||||
|
||||
for key, attr in pairs(value) do
|
||||
instance:SetAttribute(key, attr)
|
||||
for attributeName, attributeValue in pairs(value) do
|
||||
local isNameValid =
|
||||
-- For our SetAttribute to succeed, the attribute name must be
|
||||
-- less than or equal to 100 characters...
|
||||
#attributeName <= 100
|
||||
-- ...must only contain alphanumeric characters, periods, hyphens,
|
||||
-- underscores, or forward slashes...
|
||||
and attributeName:match("[^%w%.%-_/]") == nil
|
||||
-- ... and must not use the RBX prefix, which is reserved by Roblox.
|
||||
and attributeName:sub(1, 3) ~= "RBX"
|
||||
|
||||
if isNameValid then
|
||||
instance:SetAttribute(attributeName, attributeValue)
|
||||
else
|
||||
didAllWritesSucceed = false
|
||||
end
|
||||
end
|
||||
|
||||
for key in pairs(existing) do
|
||||
@@ -47,7 +63,7 @@ return {
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
return didAllWritesSucceed
|
||||
end,
|
||||
},
|
||||
Tags = {
|
||||
@@ -116,4 +132,34 @@ return {
|
||||
end,
|
||||
},
|
||||
},
|
||||
Script = {
|
||||
Source = {
|
||||
read = function(instance: Script)
|
||||
return true, ScriptEditorService:GetEditorSource(instance)
|
||||
end,
|
||||
write = function(instance: Script, _, value: string)
|
||||
task.spawn(function()
|
||||
ScriptEditorService:UpdateSourceAsync(instance, function()
|
||||
return value
|
||||
end)
|
||||
end)
|
||||
return true
|
||||
end,
|
||||
},
|
||||
},
|
||||
ModuleScript = {
|
||||
Source = {
|
||||
read = function(instance: ModuleScript)
|
||||
return true, ScriptEditorService:GetEditorSource(instance)
|
||||
end,
|
||||
write = function(instance: ModuleScript, _, value: string)
|
||||
task.spawn(function()
|
||||
ScriptEditorService:UpdateSourceAsync(instance, function()
|
||||
return value
|
||||
end)
|
||||
end)
|
||||
return true
|
||||
end,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"Version": [
|
||||
0,
|
||||
596,
|
||||
597,
|
||||
1,
|
||||
5960685
|
||||
5970668
|
||||
],
|
||||
"Classes": {
|
||||
"Accessory": {
|
||||
@@ -4504,6 +4504,17 @@
|
||||
},
|
||||
"DefaultProperties": {}
|
||||
},
|
||||
"AvatarCreationService": {
|
||||
"Name": "AvatarCreationService",
|
||||
"Tags": [
|
||||
"NotCreatable",
|
||||
"NotReplicated",
|
||||
"Service"
|
||||
],
|
||||
"Superclass": "Instance",
|
||||
"Properties": {},
|
||||
"DefaultProperties": {}
|
||||
},
|
||||
"AvatarEditorService": {
|
||||
"Name": "AvatarEditorService",
|
||||
"Tags": [
|
||||
@@ -15560,9 +15571,7 @@
|
||||
},
|
||||
"DragDetector": {
|
||||
"Name": "DragDetector",
|
||||
"Tags": [
|
||||
"NotBrowsable"
|
||||
],
|
||||
"Tags": [],
|
||||
"Superclass": "ClickDetector",
|
||||
"Properties": {
|
||||
"ActivatedCursorIcon": {
|
||||
@@ -28121,6 +28130,17 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"LogReporterService": {
|
||||
"Name": "LogReporterService",
|
||||
"Tags": [
|
||||
"NotCreatable",
|
||||
"NotReplicated",
|
||||
"Service"
|
||||
],
|
||||
"Superclass": "Instance",
|
||||
"Properties": {},
|
||||
"DefaultProperties": {}
|
||||
},
|
||||
"LogService": {
|
||||
"Name": "LogService",
|
||||
"Tags": [
|
||||
@@ -31192,7 +31212,7 @@
|
||||
},
|
||||
"Source": {
|
||||
"Name": "Source",
|
||||
"Scriptability": "ReadWrite",
|
||||
"Scriptability": "Custom",
|
||||
"DataType": {
|
||||
"Value": "String"
|
||||
},
|
||||
@@ -41454,7 +41474,7 @@
|
||||
"Properties": {
|
||||
"Source": {
|
||||
"Name": "Source",
|
||||
"Scriptability": "ReadWrite",
|
||||
"Scriptability": "Custom",
|
||||
"DataType": {
|
||||
"Value": "String"
|
||||
},
|
||||
@@ -47977,6 +47997,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"Camera Speed Adjust Binding": {
|
||||
"Name": "Camera Speed Adjust Binding",
|
||||
"Scriptability": "ReadWrite",
|
||||
"DataType": {
|
||||
"Enum": "CameraSpeedAdjustBinding"
|
||||
},
|
||||
"Tags": [],
|
||||
"Kind": {
|
||||
"Canonical": {
|
||||
"Serialization": "Serializes"
|
||||
}
|
||||
}
|
||||
},
|
||||
"Camera Zoom to Mouse Position": {
|
||||
"Name": "Camera Zoom to Mouse Position",
|
||||
"Scriptability": "ReadWrite",
|
||||
@@ -49545,7 +49578,9 @@
|
||||
},
|
||||
"StudioAttachment": {
|
||||
"Name": "StudioAttachment",
|
||||
"Tags": [],
|
||||
"Tags": [
|
||||
"NotReplicated"
|
||||
],
|
||||
"Superclass": "Instance",
|
||||
"Properties": {
|
||||
"AutoHideParent": {
|
||||
@@ -49614,52 +49649,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"DefaultProperties": {
|
||||
"Attributes": {
|
||||
"Attributes": {}
|
||||
},
|
||||
"AutoHideParent": {
|
||||
"Bool": false
|
||||
},
|
||||
"Capabilities": {
|
||||
"SecurityCapabilities": 0
|
||||
},
|
||||
"DefinesCapabilities": {
|
||||
"Bool": false
|
||||
},
|
||||
"IsArrowVisible": {
|
||||
"Bool": false
|
||||
},
|
||||
"Offset": {
|
||||
"Vector2": [
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"SourceAnchorPoint": {
|
||||
"Vector2": [
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
},
|
||||
"SourceAssetId": {
|
||||
"Int64": -1
|
||||
},
|
||||
"Tags": {
|
||||
"Tags": []
|
||||
},
|
||||
"TargetAnchorPoint": {
|
||||
"Vector2": [
|
||||
0.0,
|
||||
0.0
|
||||
]
|
||||
}
|
||||
}
|
||||
"DefaultProperties": {}
|
||||
},
|
||||
"StudioCallout": {
|
||||
"Name": "StudioCallout",
|
||||
"Tags": [
|
||||
"NotCreatable",
|
||||
"NotReplicated"
|
||||
],
|
||||
"Superclass": "Instance",
|
||||
@@ -64701,6 +64695,14 @@
|
||||
"EdgeBump": 1
|
||||
}
|
||||
},
|
||||
"CameraSpeedAdjustBinding": {
|
||||
"name": "CameraSpeedAdjustBinding",
|
||||
"items": {
|
||||
"AltScroll": 2,
|
||||
"None": 0,
|
||||
"RmbScroll": 1
|
||||
}
|
||||
},
|
||||
"CameraType": {
|
||||
"name": "CameraType",
|
||||
"items": {
|
||||
@@ -67514,6 +67516,9 @@
|
||||
"Mid": 36,
|
||||
"Midlight": 98,
|
||||
"Notification": 4,
|
||||
"OnboardingCover": 132,
|
||||
"OnboardingHighlight": 133,
|
||||
"OnboardingShadow": 134,
|
||||
"RibbonButton": 19,
|
||||
"RibbonTab": 15,
|
||||
"RibbonTabTopBar": 16,
|
||||
|
||||
@@ -3,8 +3,9 @@ local strict = require(script.Parent.strict)
|
||||
local isDevBuild = script.Parent.Parent:FindFirstChild("ROJO_DEV_BUILD") ~= nil
|
||||
|
||||
local Version = script.Parent.Parent.Version
|
||||
local realVersion = Version.Value:split(".")
|
||||
local major, minor, patch, metadata = Version.Value:match("^(%d+)%.(%d+)%.(%d+)(.*)$")
|
||||
|
||||
local realVersion = { major, minor, patch, metadata }
|
||||
for i = 1, 3 do
|
||||
local num = tonumber(realVersion[i])
|
||||
if num then
|
||||
|
||||
@@ -233,7 +233,7 @@ function PatchTree.build(patch, instanceMap, changeListHeaders)
|
||||
addProp(
|
||||
prop,
|
||||
if currentSuccess then currentValue else "[Error]",
|
||||
if incomingSuccess then incomingValue else next(incoming)
|
||||
if incomingSuccess then incomingValue else select(2, next(incoming))
|
||||
)
|
||||
end
|
||||
|
||||
@@ -359,7 +359,7 @@ function PatchTree.build(patch, instanceMap, changeListHeaders)
|
||||
if success then
|
||||
table.insert(changeList, { prop, "N/A", incomingValue })
|
||||
else
|
||||
table.insert(changeList, { prop, "N/A", next(incoming) })
|
||||
table.insert(changeList, { prop, "N/A", select(2, next(incoming)) })
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -282,7 +282,7 @@ function ServeSession:__initialSync(serverInfo)
|
||||
local unappliedPatch = self.__reconciler:applyPatch(catchUpPatch)
|
||||
|
||||
if not PatchSet.isEmpty(unappliedPatch) then
|
||||
Log.warn(
|
||||
Log.debug(
|
||||
"Could not apply all changes requested by the Rojo server:\n{}",
|
||||
PatchSet.humanSummary(self.__instanceMap, unappliedPatch)
|
||||
)
|
||||
@@ -309,7 +309,7 @@ function ServeSession:__mainSyncLoop()
|
||||
local unappliedPatch = self.__reconciler:applyPatch(message)
|
||||
|
||||
if not PatchSet.isEmpty(unappliedPatch) then
|
||||
Log.warn(
|
||||
Log.debug(
|
||||
"Could not apply all changes requested by the Rojo server:\n{}",
|
||||
PatchSet.humanSummary(self.__instanceMap, unappliedPatch)
|
||||
)
|
||||
|
||||
@@ -14,7 +14,7 @@ use tokio::runtime::Runtime;
|
||||
|
||||
use crate::{
|
||||
serve_session::ServeSession,
|
||||
snapshot::{InstanceWithMeta, RojoTree},
|
||||
snapshot::{AppliedPatchSet, InstanceWithMeta, RojoTree},
|
||||
};
|
||||
|
||||
use super::resolve_path;
|
||||
@@ -90,10 +90,12 @@ impl SourcemapCommand {
|
||||
|
||||
loop {
|
||||
let receiver = session.message_queue().subscribe(cursor);
|
||||
let (new_cursor, _patch_set) = rt.block_on(receiver).unwrap();
|
||||
let (new_cursor, patch_set) = rt.block_on(receiver).unwrap();
|
||||
cursor = new_cursor;
|
||||
|
||||
write_sourcemap(&session, self.output.as_deref(), filter)?;
|
||||
if patch_set_affects_sourcemap(&session, &patch_set, filter) {
|
||||
write_sourcemap(&session, self.output.as_deref(), filter)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,6 +118,43 @@ fn filter_non_scripts(instance: &InstanceWithMeta) -> bool {
|
||||
)
|
||||
}
|
||||
|
||||
fn patch_set_affects_sourcemap(
|
||||
session: &ServeSession,
|
||||
patch_set: &[AppliedPatchSet],
|
||||
filter: fn(&InstanceWithMeta) -> bool,
|
||||
) -> bool {
|
||||
let tree = session.tree();
|
||||
|
||||
// A sourcemap has probably changed when:
|
||||
patch_set.par_iter().any(|set| {
|
||||
// 1. An instance was removed, in which case it will no
|
||||
// longer exist in the tree and we cant check the filter
|
||||
!set.removed.is_empty()
|
||||
// 2. A newly added instance passes the filter
|
||||
|| set.added.iter().any(|referent| {
|
||||
let instance = tree
|
||||
.get_instance(*referent)
|
||||
.expect("instance did not exist when updating sourcemap");
|
||||
filter(&instance)
|
||||
})
|
||||
// 3. An existing instance has its class name, name,
|
||||
// or file paths changed, and passes the filter
|
||||
|| set.updated.iter().any(|updated| {
|
||||
let changed = updated.changed_class_name.is_some()
|
||||
|| updated.changed_name.is_some()
|
||||
|| updated.changed_metadata.is_some();
|
||||
if changed {
|
||||
let instance = tree
|
||||
.get_instance(updated.id)
|
||||
.expect("instance did not exist when updating sourcemap");
|
||||
filter(&instance)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fn recurse_create_node<'a>(
|
||||
tree: &'a RojoTree,
|
||||
referent: Ref,
|
||||
|
||||
@@ -24,7 +24,7 @@ impl<K: Hash + Eq, V: Eq> MultiMap<K, V> {
|
||||
K: Borrow<Q>,
|
||||
Q: Hash + Eq,
|
||||
{
|
||||
self.inner.get(k.borrow()).map(Vec::as_slice).unwrap_or(&[])
|
||||
self.inner.get(k).map(Vec::as_slice).unwrap_or(&[])
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, k: K, v: V) {
|
||||
|
||||
@@ -159,7 +159,7 @@ impl ApiService {
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
json_ok(&WriteResponse { session_id })
|
||||
json_ok(WriteResponse { session_id })
|
||||
}
|
||||
|
||||
async fn handle_api_read(&self, request: Request<Body>) -> Response<Body> {
|
||||
@@ -271,7 +271,7 @@ impl ApiService {
|
||||
},
|
||||
};
|
||||
|
||||
json_ok(&OpenResponse {
|
||||
json_ok(OpenResponse {
|
||||
session_id: self.serve_session.session_id(),
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user