fullmoon wrote:
Hey Chalkmarrow-
I've done a couple of tests with Snyff and 1.4 and I can't seem to get either computer to recognize sensor-updates so neither one can read the others' variables. Broadcasts work fine, though. Everything works great when I use the same setup with 1.3. Have you encountered the same problem?
I haven't looked at the latest beta with Snyff (I think the last time I tested it was four beta revs ago). It could be that they are appending something to the variable names (this was done in some of the earlier mesh experiments), which would break snyff. I suspect that's what's happening. I'll check with John.
Offline
Ah. I confirmed with Johnm that they slightly changed the way Scratch reports variables via sensor update (all variables used to have the string "Scratch-" prepended to them before being sent out, but now they don't). That's the issue.
Last edited by chalkmarrow (2009-06-08 22:34:07)
Offline
chalkmarrow wrote:
Ah. I confirmed with Johnm that they slightly changed the way Scratch reports variables via sensor update (all variables used to have the string "Scratch-" prepended to them before being sent out, but now they don't). That's the issue.
Hmmmm... Do you think it will work if we manually attach the prefix to the variable? Like using "Scratch-xpos" rather than just "xpos"?
I'm guessing broadcasts are kept the same (EDIT: Just checked, apparently not).
Last edited by technoguyx (2009-06-09 17:52:41)
Offline
this loooks really cool! so where could i find out more information, and do you need two separate projects or just one project
Offline
KingOfGames wrote:
archmage wrote:
So if you are behind a router this is how you find your IP on a PC running windows.
1. Click start
2.Click all programs
3. Click accessories
4. Click Command Prompt
5. Type ipconfig into the prompt
Now this you give you a bunch of info about your connection. Just look for something that says IP address and the number beside it is your IP address.
Or you can:
Click start
then click run
type in cmd
press enter
type in ipconfig
look for the ip. there ya go
just because there are other ways, I'll share one:
click start
click run
type command.com (which is the true dos prompt)
type in ipconfig
look for ip address
Offline
is there a way to make multiplayer without snyff?
Offline
my dad is woried about the security of snyff cuz on the download it says that the author is unknown and that the control over the computer is unlimtied so could i have like a certificte or somthing to tell me that it's not a scam?
Offline
The author of the program is chalkmarrow. The source code is also posted so you can look over it if you want to see if it contains any malicious code but I am really sure it doesn't.
Offline
archmage wrote:
The author of the program is chalkmarrow. The source code is also posted so you can look over it if you want to see if it contains any malicious code but I am really sure it doesn't.
lolz. I doubt I could write malicious code if I wanted to...
Snyff 2, btw, is written in Processing, and is different in that the interface is moved to Scratch itself (i.e., you connect to other computers and configure how it handles variables & broadcasts via Scratch) and can connect to multiple Scratch instances. Hopefully this will make it easier for people to run it and modify it (since Processing/Java is fairly easy to learn, and is free, unlike Adobe Flex/Flash). Best case, it will be done early next month.
Offline
archmage wrote:
The author of the program is chalkmarrow. The source code is also posted so you can look over it if you want to see if it contains any malicious code but I am really sure it doesn't.
where is the code posted?
Offline
hirandomperson wrote:
archmage wrote:
The author of the program is chalkmarrow. The source code is also posted so you can look over it if you want to see if it contains any malicious code but I am really sure it doesn't.
where is the code posted?
It's pretty short, so I just posted it below. The formatting is a little strange in this window, but it's still readable.
<?xml version="1.0" encoding="utf-8"?> <!-- * * S N Y F F * Scratch-to-Scratch communication * * Chalkmarrow, 2009 * Software and assets released under Creative Commons Zero (CC0): * http://wiki.creativecommons.org/CC0_FAQ * --> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" width="553" height="518" backgroundColor="#B3B5C3" viewSourceURL="srcview/index.html" borderColor="#FBF6F6" horizontalScrollPolicy="off" enabled="true" backgroundAlpha="0" horizontalAlign="center" verticalAlign="top" alpha="1" > <mx:Script><![CDATA[ import mx.controls.Alert; private var host0:String; // IP address of computer 0 private var host1:String; // IP address of computer 1 private var port0:int; // Port for computer 0 (42001=Scratch) private var port1:int; // Port for computer 1 private var s0:Socket = new Socket(); // Socket for computer 0 private var s1:Socket = new Socket(); // Socket for computer 1 // Todo: Convert to an array of sockets, rather than discrete s0, s1 // Handler for computer 0 "Connect" button private function button1Handler():void { if (s0.connected) { button1.label="Connect"; textInput1.editable=true; r1.enabled=true; r2.enabled=true; link1.visible=false; mainPanel.status="Computer 0 disconnected"; s0.close(); } else { if (r1.selected) { host0='localhost'; } else { host0=textInput1.text; } // Connect to Scratch at port0 on computer 0 // and create event listeners try { s0.connect(host0,int(port0input.text)); } catch (error:Error){ trace("0:exception"); } // Event listeners for socket s0.addEventListener(Event.CONNECT,socket0); s0.addEventListener(Event.CLOSE,socket0); s0.addEventListener(IOErrorEvent.IO_ERROR,socket0); s0.addEventListener(ProgressEvent.SOCKET_DATA, dataInHandler0) s0.addEventListener(SecurityErrorEvent.SECURITY_ERROR,socket0); } } // Handler for computer 1 "Connect" button private function button2Handler():void { if (s1.connected) { button2.label="Connect"; textInput2.editable=true; link2.visible=false; s1.close(); } else { host1=textInput2.text; // Connect to Scratch at port1 on computer 1 // and create event listeners try { s1.connect(host1,int(port1input.text)); } catch (error:Error){ trace("1:exception"); } // Event listeners for socket s1.addEventListener(Event.CONNECT,socket1); s1.addEventListener(Event.CLOSE,socket1); s1.addEventListener(IOErrorEvent.IO_ERROR,socket1); s1.addEventListener(SecurityErrorEvent.SECURITY_ERROR,socket1); s1.addEventListener(ProgressEvent.SOCKET_DATA, dataInHandler1); } } // Handler for computer 0 connection status events private function socket0(Event:Object):void { switch (Event.type) { case 'ioError' : link1.visible=false; mainPanel.status="Computer 0 cannot connect"; button1.label="Connect"; textInput1.editable=true; r1.enabled=true; r2.enabled=true; Alert.show("Could Not Connect. Make sure that remote sensors are enabled in the Scratch project on computer 0.", "Error", Alert.OK); break; case 'connect' : link1.visible=true; mainPanel.status="Computer 0 connected"; button1.label = "Disconnect"; textInput1.editable=false; r1.enabled=false; r2.enabled=false; snyffSez("hello", 0); snyffSez("ur 0", 0); if (s1.connected){ snyffSez("bothconnected",1); snyffSez("bothconnected",0); } break; case 'close' : mainPanel.status="Computer 0 disconnected"; link1.visible=false; button1.label="Connect"; textInput1.editable=true; r1.enabled=true; r2.enabled=true; break; case 'securityError' : trace ("0:security error"); break; } } // Handler for computer 1 connection status events private function socket1(Event:Object):void { switch (Event.type) { case 'ioError' : link2.visible=false; mainPanel.status="Computer 1 cannot connect"; button2.label="Connect"; textInput2.editable=true; Alert.show("Could Not Connect. Make sure that remote sensors are enabled in the Scratch project on computer 1, and that the IP address is correct", "Error", Alert.OK); break; case 'connect' : link2.visible=true; mainPanel.status="Computer 1 connected"; button2.label = "Disconnect"; textInput2.editable=false; snyffSez("hello", 1); snyffSez("ur 1", 1); if (s0.connected){ snyffSez("bothconnected",0); snyffSez("bothconnected",1); } break; case 'close' : link2.visible=false; mainPanel.status="Computer 1 disconnected"; button2.label="Connect"; textInput2.editable=true; break; case 'securityError' : trace ("security error"); break; } } // Handler for incoming data from computer 0 private function dataInHandler0(event:ProgressEvent):void { var inString:String = ""; while (s0.bytesAvailable){ inString+=s0.readUTF(); } parseAndDo(inString,0); } // Handler for incoming data from computer 1 private function dataInHandler1(event:ProgressEvent):void { var inString:String = ""; while (s1.bytesAvailable){ inString+=s1.readUTF(); } parseAndDo(inString,1); } // Show or hide design helper components private function designHelperToggled():void{ if (checkbox1.selected) { designHelper.visible=true; link3.visible=true; mainPanel.height=450; port0input.editable=true; // Allow editing of ports when Design Helper is open port0input.enabled=true; // Must be 42001 to connect to Scratch port1input.editable=true; port1input.enabled=true; consoleOut("---Beginning trace of input/output---"); } else { designHelper.visible=false; link3.visible=false; mainPanel.height=280; port0input.editable=false; port0input.enabled=false; port1input.editable=false; port1input.enabled=false; consoleOut("---Ending trace of input/output---"); } } // Design helper broadcast private function broadcastHelper():void{ sendScratchBroadcast(broadcastInput.text, computerSelect.selectedIndex); } // Design helper sensor update private function updateHelper():void{ sendScratchSensorUpdate(updateVarName.text, updateVal.text, computerSelect.selectedIndex); } // // Main parsing and handling function for data received from either socket // private function parseAndDo(inString:String, sourceSocket:int):void{ var broadcastArgs:Array; // Array used for snyff commands if (designHelper.visible){ consoleOut("From "+sourceSocket+" : "+inString); // Text area output } // Check for sensor update of string value var pattern2:RegExp = /"Scratch-(.*?)"\s"(.*?)"/g; result = pattern2.exec(inString); while (result != null){ trace(result[1]+" changed to string "+result[2]); sendScratchSensorUpdate(result[1], result[2], 1-sourceSocket); result = pattern2.exec(inString); } // Check for sensor update of numeric value // Todo: Clean this up -- will misinterpret certain strings // as numbers. var pattern3:RegExp = /"Scratch-(.*?)"\s([-|\d|.]+)/g; result = pattern3.exec(inString); while (result != null){ trace(result[1]+" changed to number ["+result[2]+"]"); sendScratchSensorUpdate(result[1], result[2], 1-sourceSocket); result = pattern3.exec(inString); } // Check for broadcasts var pattern1:RegExp = /broadcast\s"(.*?)"/g; var result:Object = pattern1.exec(inString); while (result != null){ // Look for snyff command in broadcast if (result[1].indexOf("snyff")>-1){ // Handle synff command broadcastArgs=result[1].split(" "); switch(broadcastArgs[1]){ // Received ping command to see who's connected case "ping": if (s0.connected && s1.connected) { // Both connected snyffSez("pingreply 2", sourceSocket); } else { // Only you are connected snyffSez("pingreply 1", sourceSocket); } break; // Include additional snyff command cases later, e.g., serial output // to serproxy, xml, twitter API, save data, etc. } } else { // Forward regular broadcast to other computer, unless it starts with @ // or is a StartClicked event (consider changing this so clicking flag // starts both instances) if ((result[1].charAt(0)!="@") && (result[1]!="Scratch-StartClicked")) { // If first char is ">", replace with "<" if (result[1].charAt(0)==">") { result[1]="<"+result[1].substring(1); } sendScratchBroadcast(result[1], 1-sourceSocket); } } result = pattern1.exec(inString); } } // General function for sending data to a socket private function sendToScratch(dataOut:String, toSocket:int):void { var sizeBytes:ByteArray = new ByteArray(); var i:int; // Todo: Need to generalize for more than 255 characters (use bitwise operators) sizeBytes[0]=0; sizeBytes[1]=0; sizeBytes[2]=0; sizeBytes[3] = dataOut.length; if (toSocket==1 && s1.connected){ for (i=0; i<4; i++) { s1.writeByte(sizeBytes[i]); } s1.writeMultiByte(dataOut, "us-ascii"); if (designHelper.visible){ consoleOut("To "+toSocket+" : "+dataOut); } s1.flush(); } else if (toSocket==0 && s0.connected){ for (i=0; i<4; i++) { s0.writeByte(sizeBytes[i]); } s0.writeMultiByte(dataOut, "us-ascii"); if (designHelper.visible){ consoleOut("To "+toSocket+" : "+dataOut); } s0.flush(); } } // Send broadcast to a particular socket private function sendScratchBroadcast(broadcast:String, toSocket:int):void{ sendToScratch('broadcast "'+broadcast+'"', toSocket); } // Send sensor update to a particular socket private function sendScratchSensorUpdate(variable:String, value:String, toSocket:int):void{ sendToScratch('sensor-update '+variable+' '+value, toSocket); } // Send snyffsez message to a particular socket private function snyffSez(dataOut:String, toSocket:int):void { sendToScratch('broadcast "snyffsez '+dataOut+'"', toSocket); } // Send output to console in Design Helper private function consoleOut(dataOut:String):void { console.text+=dataOut+"\n"; console.validateNow(); console.verticalScrollPosition = console.maxVerticalScrollPosition+1; } // MXML script for user interface buttons, etc. ]]></mx:Script> <mx:RadioButtonGroup id="radiogroup1"/> <mx:Panel width="454" layout="absolute" id="mainPanel" title="Snyff/Scratch Connections" backgroundColor="#D8D9DA" borderColor="#DBDAD7" height="280" verticalScrollPolicy="off" horizontalScrollPolicy="off" horizontalAlign="center" verticalAlign="top" alpha="1" visible="true"> <mx:Canvas width="428" height="228" x="6" y="5" backgroundColor="#CBC3C3" backgroundAlpha="0.0" verticalScrollPolicy="off"> <mx:Image x="20" y="-7" width="359" height="160" source="assets/composite.png"/> <mx:Button x="37.5" y="114" label="Connect" click="button1Handler();" enabled="true" cornerRadius="5" id="button1" height="24" width="113" fontSize="10" labelPlacement="top" fillAlphas="[0.6, 1.0, 1.0, 1.0]" fillColors="[#F0F1EF, #C8CCC5]" toolTip="Connect to computer 0"/> <mx:TextInput x="264.5" y="178" id="textInput2" enabled="true" maxChars="16" displayAsPassword="false" editable="true" width="98" height="21" toolTip="Internet Protocol address (like 192.168.0.10)"/> <mx:Button x="251.5" y="114" label="Connect" click="button2Handler();" enabled="true" cornerRadius="5" id="button2" height="24" width="113" fontSize="10" fillAlphas="[0.6, 1.0, 1.0, 1.0]" fillColors="[#F0F1EF, #C8CCC5]" toolTip="Connect to computer 1"/> <mx:Text x="260.5" y="159" text="IP address:" fontSize="10"/> <mx:RadioButton x="46.5" y="143" id="r1" label="'localhost'" selected="true" groupName="radiogroup1" click="textInput1.enabled=false;" toolTip="(This computer)" fontSize="10" height="15"/> <mx:RadioButton x="46.5" y="157" id="r2" label="IP address:" groupName="radiogroup1" click="textInput1.enabled=true;textInput1.editable=true;" fontSize="10"> <mx:toolTip>IP address you're trying to connect to (e.g., 192.62.0.1)</mx:toolTip> </mx:RadioButton> <mx:TextInput x="46.5" y="178" id="textInput1" enabled="false" maxChars="16" displayAsPassword="false" editable="false" width="104" height="21" toolTip="Internet Protocol address (like 192.168.0.10)"/> <mx:Image x="132.5" y="33" width="75" height="53" id="link1" visible="false" source="assets/link1.png"/> <mx:Image x="213.5" y="52" width="57" height="28" id="link2" visible="false" source="assets/link2.png"/> <mx:Image x="182.5" y="57" width="55.5" height="178" source="assets/link3.png" scaleContent="true" id="link3" visible="false"/> <mx:CheckBox id="checkbox1" selected="false" enabled="true" click="designHelperToggled();" x="190" y="80" textAlign="left" toolTip="Scratch Design Helper"/> <mx:TextInput x="78" y="202" width="49.5" id="port0input" text="42001" editable="false" fontSize="9" maxChars="7" height="20" color="#070707" enabled="false"> <mx:toolTip>This port should always be 42001 for Scratch connections</mx:toolTip> </mx:TextInput> <mx:TextInput x="298" y="201" width="49.5" id="port1input" text="42001" editable="false" fontSize="9" maxChars="7" height="20" color="#070707" enabled="false"> <mx:toolTip>This port should always be 42001 for Scratch connections</mx:toolTip> </mx:TextInput> <mx:Text x="46" y="202" text="Port:"/> <mx:Text x="264.5" y="202" text="Port:"/> </mx:Canvas> <mx:Canvas x="22" y="107" width="390" height="300" id="designHelper" visible="false"> <mx:ComboBox x="331" y="141" width="45.5" height="20" toolTip="Choose computer to send to" fontSize="9" id="computerSelect" selectedIndex="0" enabled="true"><mx:ArrayCollection><mx:String>0</mx:String><mx:String>1</mx:String></mx:ArrayCollection> </mx:ComboBox> <mx:TextInput x="114" y="127" width="104.5" id="updateVarName" editable="true" enabled="true" text="test" toolTip="Variable name" fontSize="12"/> <mx:TextInput x="241.5" y="127" width="76.5" id="updateVal" editable="true" enabled="true" text="0" toolTip="Variable value" fontSize="12"/> <mx:Button x="23" y="127" label="update" click="updateHelper();" id="updateButton" enabled="true" width="83" toolTip="Send sensor update to Scratch"/> <mx:Text x="224.5" y="129" text="=" id="equalsLabel"/> <mx:TextInput width="203.5" id="broadcastInput" text="hello world" editable="true" enabled="true" x="114.5" y="155" toolTip="Broadcast to send" fontSize="12"/> <mx:Button label="broadcast" click="broadcastHelper();" id="broadcastButton" x="23" y="155" toolTip="Send broadcast to Scratch"/> <mx:HRule x="10" y="121" width="370" strokeColor="#646B6B"/> <mx:Text x="323" y="124" text="computer:"/> <mx:TextArea x="23" y="198" width="357" id="console" maxChars="1000" wordWrap="false" editable="false" enabled="true" backgroundColor="#C2BEBE" color="#1E1E1E" cornerRadius="4" borderColor="#8C8D8E" height="96" verticalScrollPolicy="on" liveScrolling="true" visible="true"/> </mx:Canvas> </mx:Panel> </mx:WindowedApplication>
Last edited by chalkmarrow (2009-07-09 15:50:53)
Offline
Paddle2See wrote:
KingOfGames wrote:
Or you can:
Click start
then click run
type in cmd
press enter
type in ipconfig
look for the ip. there ya goVista doesn't have a Run button...you have to find the Command Prompt application
at the bottom you can type in run. and can somebody show me how to get command prompt up on linux?
Offline
darkgamemaker: The current Snyff only works with Scratch 1.3. I'm working on a version for 1.4, but it's substantially different, and is taking a while...
Offline
Cool, I'd like to download it sometime
Offline
hirandomperson wrote:
my dad is woried about the security of snyff cuz on the download it says that the author is unknown and that the control over the computer is unlimtied so could i have like a certificte or somthing to tell me that it's not a scam?
Same here, my dad is being cautious about it because there actually IS the little chance of someone SOMEHOW HACKING
Offline
chazmaniandevel wrote:
Paddle2See wrote:
KingOfGames wrote:
Or you can:
Click start
then click run
type in cmd
press enter
type in ipconfig
look for the ip. there ya goVista doesn't have a Run button...you have to find the Command Prompt application
at the bottom you can type in run. and can somebody show me how to get command prompt up on linux?
click the green dragon in the botm left corner and at the top of the menu type
Terminal
click on terinal and type
ifconfig
Offline
chalkmarrow wrote:
For those of you who would like to play around with linking two Scratch projects over a network, but don't want to mess around with Python, this Adobe AIR program might be of interest:
http://scratchconnections.wik.is/User:Chalkmarrow/Snyff
http://scratchconnections.wik.is/@api/d … age005.png
Basically, when two computers are hooked up, broadcasts from one computer are also seen by the other, and global variables from one computer show up as sensor values in the other. There are also some special features to make things easier to design multi-player projects.
It is based on archmage's idea of using Flash as the go-between, and is written in Adobe Flex (MXML + Actionscript 3). It runs as an executable file on any platform, and is simple to use.
The source code is included on the site (or you can just right click the application).
Once you have two computers hooked up, Snyff operates in accordance with only four simple rules:
1. Every global variable (not list or local variable) you change or create in one computer appears as a sensor value (blue blocks) in the other computer.
2. Every broadcast in one computer gets sent as a broadcast to the other computer, except:
3. Every broadcast that starts with "@" is _not_ sent to the other computer, and
4. Every broadcast that starts with ">" is changed to start with "<" and _then_ sent to the other computer.
That's it.
Amazing!Can you host a world wide multiplayer world?
Last edited by jake451998 (2010-01-30 11:39:31)
Offline
This program was limited to two machines talking. The beta Mesh functionality that was in one of the versions of Scratch (you can search for it in the forums) would let lots of computers talk to each other, but it gets fairly messy because every broadcast is heard by every sprite everywhere.
Offline
Zeratul wrote:
oh god how do u use the snyff???????????????
Snyff is kind of advanced, you would much rather use Jens' BYOB mesh feature.
(No offense to Chalkmarrow, Snyff is amazing)
Offline
This works?
Offline
Hi chalkmarrow,
Has there been any progress on a version of Snyff for Scratch 1.4? I'm interested in looking into it for teaching a course in the near future. Any update would be nice -- thanks!
Offline