├── README.md ├── delete2.php ├── functions.php ├── index.php ├── info2.php ├── list2.php ├── load2.php ├── save3.php └── show2.php /README.md: -------------------------------------------------------------------------------- 1 | # What is this? 2 | This is a clone of SmileBOOM's SmileBASIC servers. With this, no NNID is needed, everything is published automatically, there are no upload limits, and uploaded files are accessible from the web. 3 | It also makes requests to SmileBASIC's original servers so you can still download keys from there. 4 | 5 | # How to use this 6 | You need: 7 | * Somewhere to host it 8 | * PHP installed 9 | * The PHP GD extension 10 | * PHP should have access to the folder you're putting it in 11 | * A url that isn't too long as there's only around 40 chars available for urls in the binaries 12 | * CFW on your 3DS 13 | 14 | Once you have all that there are two ways to install the necessary modifications on your 3DS: 15 | * If you have version 3.6.0 of SmileBASIC, you can use the .ips generator in index.php to download a code.ips file 16 | * If you use Luma3DS, you can place this file into /luma/titles/000400000016DE00/code.ips 17 | * Modify the code.bin of SmileBASIC 18 | * Dump a decompressed code.bin from SmileBASIC 19 | Here's one way to do this: 20 | * Make sure you have the latest release of GodMode9 21 | * Open GodMode9 and navigate to A:/title/0004000e/0016de00/content 22 | * Press A while highlighting 00000000.tmd and select "TMD file options..." -> "Extract .code" 23 | * You now have the code.bin of SmileBASIC in /gm9out/.code on your SD card 24 | * Submit your code.bin to the patcher in index.php 25 | It should patch the binary to use whatever url you put the server in 26 | * Load the code.bin over SmileBASIC's 27 | If you use Luma3DS, put your modified code.bin into /luma/titles/000400000016DE00/code.bin and make sure "Enable game patching" is checked in Luma's settings 28 | 29 | After you have done this, you should then be able to just use the interface as usual 30 | 31 | # Information 32 | * The server determines what account you're using from the token your 3DS sends 33 | All but the last 32 characters are constant per machine 34 | * Keys are between 4 and 9 characters long, always start with 0, and contain uppercase letters and numbers 35 | If you want to change that see the do{}while() loop in save3.php 36 | * The server sends the "X-Petc-Rights: 1" header, which tells SmileBASIC that you bought gold membership 37 | -------------------------------------------------------------------------------- /delete2.php: -------------------------------------------------------------------------------- 1 | $val){ 47 | if($name!="http_code" && !is_numeric($name)){ 48 | header($name.": ".$val); 49 | } 50 | } 51 | echo("OK"); 52 | } 53 | } 54 | 55 | -------------------------------------------------------------------------------- /functions.php: -------------------------------------------------------------------------------- 1 | $val){ 69 | if($name!="http_code" && !is_numeric($name)){ 70 | header($name.": ".$val); 71 | } 72 | } 73 | if($load){ 74 | echo($sb); 75 | }else{ 76 | echo("OK"); 77 | } 78 | } 79 | } 80 | } 81 | } 82 | 83 | function getkeydata($key){ 84 | if(strlen($key)<15 && !preg_match("/\.|[a-z]/",$key) && file_exists($key) && is_dir($key)){ 85 | $c=array(); 86 | $config=file_get_contents("$key/about"); 87 | $config=explode("\n",$config); 88 | foreach($config as $cfg){ 89 | $tempvar=explode(": ",$cfg); 90 | $c[$tempvar[0]]=$tempvar[1]; 91 | } 92 | $c["filesize"]=filesize("$key/raw"); 93 | return $c; 94 | }else{ 95 | return false; 96 | } 97 | } 98 | 99 | function getallkeys(){ 100 | global $id; 101 | $files=scandir("."); 102 | $out=array(); 103 | foreach($files as $k){ 104 | $c=getkeydata($k); 105 | if($c!=false && $c["ID"]==$id){ 106 | $out[$k]=$c; 107 | } 108 | } 109 | return $out; 110 | } 111 | 112 | function geturl($url,$headers){ 113 | $context=stream_context_create(array( 114 | "ssl"=>array( 115 | "verify_peer"=>false, 116 | "verify_peer_name"=>false, 117 | ), 118 | "http"=>array( 119 | 'method'=>"GET", 120 | 'header'=>$headers 121 | ) 122 | )); 123 | $res=file_get_contents($url,false,$context); 124 | global $response_headers; 125 | $response_headers=array(); 126 | for($s=0;$s"save3.php", 9 | //hex2bin("05685c")=>"save3.php", 10 | hex2bin("0575c4")=>"load2.php", 11 | //hex2bin("0574d4")=>"load2.php", 12 | hex2bin("058360")=>"save3.php", 13 | //hex2bin("05826c")=>"save3.php", 14 | hex2bin("0588dc")=>"show2.php", 15 | //hex2bin("0587e4")=>"show2.php", 16 | hex2bin("058e10")=>"load2.php", 17 | //hex2bin("058cf8")=>"load2.php", 18 | hex2bin("05a25c")=>"list2.php", 19 | //hex2bin("05a184")=>"list2.php", 20 | hex2bin("05a38c")=>"delete2.php", 21 | //hex2bin("05a2b8")=>"delete2.php", 22 | hex2bin("05a4f8")=>"info2.php" 23 | //hex2bin("05a424")=>"info2.php" 24 | ); 25 | foreach($patches as $addr=>$val){ 26 | $f.=$addr.hex2bin("0024").$urlbase.$val.str_repeat("\000",36-strlen($urlbase.$val)); 27 | } 28 | $f.="EOF"; 29 | header("Content-Disposition: attachment; filename=\"code.ips\""); 30 | die($f);//exit 31 | } 32 | if(!empty($_FILES["codebin"])){//patch code.bin 33 | $urlbase="http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI']; 34 | $urlbase=substr($urlbase,0,strrpos($urlbase,"/")+1); 35 | $diff=strlen($urlbase)-strlen("https://save.smilebasic.com/"); 36 | if($_FILES['codebin']['error']==UPLOAD_ERR_INI_SIZE || $_FILES['codebin']['error']==UPLOAD_ERR_FORM_SIZE){ 37 | die("Sorry, the file was too large to process"); 38 | } 39 | $f=file_get_contents($_FILES["codebin"]["tmp_name"]); 40 | $files=scandir("."); 41 | foreach($files as $filename){ 42 | if(preg_match("/\.php/",$filename)){ 43 | $find="https://save.smilebasic.com/".$filename;//there are two subdomains for some reason 44 | $find2="https://load.smilebasic.com/".$filename; 45 | if($diff>=0){$find.=str_repeat("\000",$diff);$find2.=str_repeat("\000",$diff);}//null pad whichever one is shorter 46 | $replace=$urlbase.$filename; 47 | if($diff<0){$replace.=str_repeat("\000",$diff*-1);} 48 | $f=str_replace($find,$replace,$f); 49 | $f=str_replace($find2,$replace,$f); 50 | } 51 | } 52 | header("Content-Disposition: attachment; filename=\"code.bin\""); 53 | die($f);//exit 54 | } 55 | 56 | if(isset($_SERVER["PATH_INFO"])){ 57 | $path=$_SERVER["PATH_INFO"]; 58 | }else{$path="";} 59 | if(strlen($path)==0){//not requesting info on any files, show main page ?> 60 | 61 | 62 | SmileBASIC Server 63 | 64 | 65 |

Projects:

66 | $key: ".$c["Filename"]."
"; 72 | } 73 | } 74 | ?> 75 |
76 |

Patcher:

77 |
78 | 79 | 80 |
81 |

IPS Generator for SmileBASIC 3.6.0

82 |
83 | 84 | 85 |
86 | 87 | 88 | 97 | 98 | 99 | 100 | An error 101 | 102 | 103 | 104 | Bad 105 | 106 | 107 | just echo it and quit 159 | header("Content-type: application/octet-stream"); 160 | header("Content-disposition: attachment;filename=\"$filename\""); 161 | die($f); 162 | } 163 | if(isset($_GET["txt"]) && !is_null($_GET["txt"])){//txt -> verify text file, just strip header and footer 164 | if(s($f,2,2)!=0){bad();} 165 | header("Content-type: text/plain"); 166 | die(substr($f,80,strlen($f)-100)); 167 | } 168 | if(isset($_GET["png"]) && !is_null($_GET["png"])){//png -> verify grp, parse image 169 | if(s($f,2,2)!=1){bad();}//check dat 170 | $fd=substr($f,80,strlen($f)-100); 171 | if(s($f,4,1)!=0){ 172 | $fd=zlib_decode($fd); 173 | } 174 | if(st($fd,80-80,8)!="PCBN0001"){bad();}//check dat magic 175 | if(s($fd,88-80,2)!=3){bad();}//check dat color 176 | if(s($fd,90-80,2)!=2){bad();}//check 2d 177 | $dim=array(s($fd,92-80,4),s($fd,96-80,4));//get dimensions 178 | $im=imagecreatetruecolor($dim[1],$dim[0]);//make it 179 | imagealphablending($im,false); 180 | imagesavealpha($im,true);//yes there can be transparency 181 | $tr=imagecolorallocatealpha($im,0,0,0,127);//transparent color 182 | imagefill($im,0,0,$tr);//fill transparency 183 | for($x=0;$x<$dim[1];$x++){ 184 | for($y=0;$y<$dim[0];$y++){ 185 | $index=108+($x+$y*$dim[0])*2;//offset in file 186 | $col=s($fd,$index-80,2);//get color data 187 | if(($col & 1)==0){continue;}//skip transparent pixels, the image is pre-filled with transparency 188 | $b=($col & 0b0000000000111110)/0b10*256/32; 189 | $g=($col & 0b0000011111000000)/0b1000000*256/32; 190 | $r=($col & 0b1111100000000000)/0b100000000000*256/32; 191 | $color=imagecolorexact($im,$r,$g,$b);//is it in the palette already 192 | if($color==-1){ 193 | $color=imagecolorallocate($im,$r,$g,$b);//get in there 194 | } 195 | imagesetpixel($im,$x,$y,$color);//set the pixel in the image 196 | } 197 | } 198 | header("Content-type: image/png");//tell the browser that it's a png 199 | imagepng($im);//do the thing 200 | imagedestroy($im); 201 | die(); 202 | } 203 | } 204 | 205 | $filepath=$key; 206 | $filename=$c["Filename"]; 207 | function parsefilepath($re){ 208 | global $filepath,$filename,$f,$p; 209 | if(isset($p[$re]) && strlen($p[$re])>0 && s($f,2,2)!=2){bad();} 210 | if(empty($p[$re])){ 211 | formats($f,$filename); 212 | }else{ 213 | $f=getfilebyname($f,$p[$re]); 214 | $filepath=$filepath."/".$p[$re]; 215 | $filename=$p[$re]; 216 | parsefilepath($re+1); 217 | } 218 | } 219 | parsefilepath(1); 220 | 221 | function parse($f,$name,$path){ 222 | $t=s($f,2,2); 223 | if($t==0){//this feels wrong 224 | $type="TXT"; 225 | }elseif($t==1){ 226 | $type="DAT"; 227 | }elseif($t==2){ 228 | $type="PRJ"; 229 | }else{ 230 | $type="UNK"; 231 | } 232 | $compressed=s($f,4,1); 233 | ?> 234 | 235 | 236 | 237 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 275 | 276 | 4){$dim=4;} 290 | $dims=array(); 291 | $dimstring=""; 292 | for($i=0;$i<$dim;$i++){ 293 | $dims[$i]=s($fd,92+$i*4-80,4); 294 | $dimstring.=($i==0?"":"x").$dims[$i]; 295 | } 296 | ?> 297 | 298 | 299 | 313 | 314 | 315 | 316 |
Name:
Formats: 238 | Raw 239 | Text';} ?> 240 | PNG';} 247 | } ?> 248 |
Type:
Icon:
Size:
Compressed:
Files:"; 273 | } 274 | ?>
DAT info: 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 |
Type:
Dimensions:
312 |
317 | 321 | 322 | 323 | 324 | <?php echo "$filepath: $filename"; ?> 325 | 326 | 327 | 328 |

329 | 330 | 331 | 332 | -------------------------------------------------------------------------------- /info2.php: -------------------------------------------------------------------------------- 1 | $about){ 23 | if($out!="" && substr($out,strlen($out)-1,1)!="\n"){ 24 | $out.="\n"; 25 | } 26 | $out.=$key."\t".$about["Filename"]."\tdate date\t".$about["filesize"]."\t3\t127"; 27 | } 28 | echo($out); -------------------------------------------------------------------------------- /load2.php: -------------------------------------------------------------------------------- 1 |