Backend Development

CodeCanyon- ByteScrambler

Submitted by Ridel, , Thread ID: 34270

Thread Closed
Ridel
Newbie
Level:
0
Reputation:
0
Posts:
18
Likes:
1
Credits:
10
13-05-2017, 05:20 PM
#1
Heiii , bytescramblerIs to protect your php code.
Demo :https://codecanyon.net/item/bytescrambler/79280
ByteScrambler.php->
Quote:<?php

class ByteScrambler{

/**
*
*@var int
*/
private $_splitLine = 40;

/**
* @var string
*/
private $_code;

/**
* @var string
*/
private $_comment = "";

/**
* @var string
*/
private $_checksum;

/**
* @var int
*/
private $_expiredate;

/**
* @var int
*/
private $_expiremessage;

/**
* @var int
*/
private $_expirecallback;

/**
* @var int
*/
private $_validhosts;

private $_validhostsmessage;

const NEWLINE = "\n";

/**
* Set code
*
* @param string $code
*/
public function SetCode($code){
$this->_code = $code;
}

/**
* Clean string, replace chars
*
* @param string $string
* @access private
*/
private function clean($string){
$find = array("<?php" , "?>");
$replace = array("" , "");
return str_replace($find, $replace, $string);
}

/**
* Split lines
*
* @param string $code
* @access private
*/
private function splitLines($code){
$splittedcode = "";
$length = strlen($code);
$parts = ceil($length / $this->_splitLine);
for($i=0 ; $i < $parts ; $i++){
$splittedcode .= substr($code, ($i*$this->_splitLine), $this->_splitLine) . "\n";
}
return $splittedcode;
}

/**
* Encode the string
*
* @param string $code
* @return string
* @access private
*/
public function Encode($code, $gzalias='gzinflate', $base64alias='base64_decode'){
return "eval(" . $gzalias . "(base64_decode('" . base64_encode(gzdeflate($code)) . "')));";
}

/**
* Add code tags
*
* @param string $code
* @return string
* @access private
*/
private function addCodeTags($code){
return "<?php \n " . $code . "?>";
}

/**
* Add functions obfuscation
*
* @param string $code
* @return string
* @access private
*/
private function addFunctions($code){

$keystroke1 = "wdr159sq4ayez7xcgnf_tv8nluk6jhbio32mp";
$keystroke2 = "wdr159sq4ayez7xcgnf_tv8nluk6jhbio32mp";

$functions = '$keystroke1 = base64_decode("' . base64_encode($keystroke1) . '");';
$functions .= "\n";
$functions .= $this->Encode('if(!function_exists("rotencode")){function rotencode($string,$amount) { $key = substr($string, 0, 1); if(strlen($string)==1) { return chr(ord($key) + $amount); } else { return chr(ord($key) + $amount) . rotEncode(substr($string, 1, strlen($string)-1), $amount); }}}');
$functions .= "\n";
$functions .= $this->obfuscateFunction($keystroke1, 'rotencode', '$keystroke1', 'O0O0O0O0O0O0');
$functions .= "\n";
$functions .= '$keystroke2 = $O0O0O0O0O0O0("' . $this->rotEncode($keystroke1,1) . '", -1);';
$functions .= "\n";
$functions .= $this->obfuscateFunction($keystroke2, 'gzinflate', '$keystroke2', 'OO000OO000OO');
$functions .= "\n";
$functions .= $this->obfuscateFunction($keystroke1, 'base64_decode', '$keystroke1', 'O0000000000O');
$functions .= "\n";
return $functions . $code;
}

/**
* Create obfuscated functionname
*/
private function obfuscateFunction($keystroke, $function, $keystrokevar, $newfunctionname){
$keystrokelen = strlen($keystroke);
$functionlen = strlen($function);

// Create keystroke id list
$keystrokeid = array();
for($i=0;$i < $keystrokelen;$i++){
$keystrokeid[$keystroke[$i]] = $i;
}

// Create obfuscated function name
$functionconcat = "";
for($i=0;$i < $functionlen;$i++){
$functionconcat .= $keystrokevar . "[" . $keystrokeid[$function[$i]] . "].";
}
return '$' . $newfunctionname . '=' . substr($functionconcat,0,-1) . ';';
}

/**
* Rotate encoding
*
* @param string $string
* @param int $amount
* @return string
* @access private
*/
private function rotEncode($string,$amount) {
$key = substr($string, 0, 1);
if(strlen($string)==1) {
return chr(ord($key) + $amount);
} else {
return chr(ord($key) + $amount) . $this->rotEncode(substr($string, 1, strlen($string)-1), $amount);
}
}

/**
* Add Comment
*
* @param string $code
* @return $code
* @access private
*/
private function addComment($code){
if(!empty($this->_comment)){
$commentline = "/* " . $this->_comment . " */\n";
return $commentline . $code;
}
return $code;
}

/**
* Set comment string
*
* @param string $string
* @return void
* @access private
*/
public function SetComment($string){
$this->_comment = $string;
}

/**
* Add expire functionality
*
* @param string $code
* @return $code
* @access private
*/
private function addExpire($code){

// date, message, callhome address
$expire_code = "";

if(!empty($this->_expiredate) && !empty($this->_expiremessage) && empty($this->_expirecallback)){
$expire_code = 'if(date("Ymd") > ' . $this->_expiredate . '){' . self::NEWLINE;
$expire_code .= 'echo "' . $this->_expiremessage . '";' . self::NEWLINE;
$expire_code .= 'exit;' . self::NEWLINE;
$expire_code .= '}' . self::NEWLINE;
}

if(!empty($this->_expiredate) && !empty($this->_expiremessage) && !empty($this->_expirecallback)){
$expire_code = 'if(date("Ymd") > ' . $this->_expiredate . '){' . self::NEWLINE;
$expire_code .= '@file_get_contents("' . $this->_expirecallback . '?host=" . $_SERVER[\'HOST\']);' . self::NEWLINE;
$expire_code .= 'echo "' . $this->_expiremessage . '";' . self::NEWLINE;
$expire_code .= 'exit;' . self::NEWLINE;
$expire_code .= '}' . self::NEWLINE;
}

return $expire_code . $code;
}

/**
* Set expire
*
* @param string $string
* @return void
* @access private
*/
public function SetExpire($date, $message="License expired", $callback=null){
$this->_expiredate = $date;
$this->_expiremessage = $message;
if($callback != "") $this->_expirecallback = $callback;
}

/**
* Set expire
*
* @param string $string
* @return void
* @access private
*/
private function addValidHost($code){

$validhost_code = "";
if(!empty($this->_validhosts)){
if(is_array($this->_validhosts)){
$validhost_code = '$found = FALSE;' . self::NEWLINE;
$validhost_code .= 'foreach(array("' . implode("\",\"", $this->_validhosts) . '") as $host){' . self::NEWLINE;
$validhost_code .= 'if(strstr($_SERVER[\'HTTP_HOST\'],$host)) $found = TRUE;' . self::NEWLINE;
$validhost_code .= '}' . self::NEWLINE;
$validhost_code .= 'if(!$found) exit("' . $this->_validhostsmessage . '");' . self::NEWLINE;
}else{
$validhost_code = 'if(!strstr($_SERVER[\'HTTP_HOST\'],"' . $this->_validhosts . '")) exit("' . $this->_validhostsmessage . '");';
}
}

return $validhost_code . "\n" . $code;
}

/**
* Set Valid hosts
*
* @param string $string
* @return void
* @access private
*/
public function SetValidHosts($host, $message="Invalid host"){
$this->_validhosts = $host;
$this->_validhostsmessage = $message;
}

/**
* Add fixed home
*
* @param string $code
* @return $code
* @access private
*/
private function addHome(){
// array van hostnames of ip adressen

}

/**
* Get Encoded code
*
* @access public
*/
public function GetEncodedCode(){
//$code = $this->EncodeBlock($this->_code);
$code = preg_replace_callback('/<\?php(.*?)\?>/is',array( &$this, 'EncodeBlock'), $this->_code);
return $code;

}

/**
* Encode this code
*/
public function EncodeBlock($code) {

// Clean code
$code = $this->clean($code[1]);

// Add expire
$code = $this->addExpire($code);

// Add valid host
$code = $this->addValidHost($code);

// Encode code
for($i=0;$i<10;$i++){
$code = $this->Encode($code, '$OO000OO000OO', '$O0000000000O');
}

// Split lines
$code = $this->splitLines($code);

// Add functions
$code = $this->addFunctions($code);

// Add Comment
$code = $this->addComment($code);

// Add code tags
$code = $this->addCodeTags($code);

return $code;
}

}



enc.php->
Quote:<?php

$encoded = "";

if(isset($_POST['txtscript'])){

// Declarations
$comment = htmlspecialchars($_POST['txtcomment']);
$chkexpire = htmlspecialchars($_POST['chkexpire']);
$expiredate = htmlspecialchars($_POST['txtexpiredate']);
$expiremessage = htmlspecialchars($_POST['txtexpiremessage']);
$chkvalidhosts = htmlspecialchars($_POST['chkvalidhosts']);
$validhosts = htmlspecialchars($_POST['txtvalidhosts']);
$validhostsmessage = htmlspecialchars($_POST['txtvalidhostsmessage']);
$script = stripslashes($_POST['txtscript']);
$expiredate = htmlspecialchars($_POST['txtexpiredate']);

if($chkexpire == "true" && (!is_numeric($expiredate) || strlen($expiredate) != 8)) $errors[] = "Expire date must be of formated like yearmonthday. For example: if you want the script to expire on 4 december 2009 you fill in 20091204.";
if($chkvalidhosts == "true" && empty($validhosts)) $errors[] = "Fill in at least 1 host. To add more then one host sepperate them with a comma.";
if(empty($script)) $errors[] = "Give in a script you want to encode";

if(count($errors) == 0){

// Include the class
include("ByteScrambler.php");

$Encoder = new ByteScrambler();
$Encoder->SetCode($script);

// Place comment
if(!empty($script)){
$Encoder->SetComment($comment);
}

// Add expire
if($chkexpire == "true"){
$Encoder->SetExpire($expiredate, $expiremessage);
}

// Add validate host
if($chkvalidhosts == "true"){
$parts = explode(",", $validhosts);
$cleanhosts = array();
foreach($parts as $host){
$cleanhosts[] = trim($host);
}
$Encoder->SetValidHosts($cleanhosts, $validhostsmessage);
}

// Encode script
$encoded = $Encoder->GetEncodedCode();

if(isset($_POST['btnsave'])){
header('Content-type: application/x-httpd-php');
header('Content-Disposition: attachment; filename="encoded.php"');
echo $encoded;
exit;
}

}

}

?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"><head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>ByteScrambler</title>
<style type="text/css">
<!--
@charset "utf-8";
/* CSS Document */
body, html, div, blockquote, img, label, p, h1, h2, h3, h4, h5, h6, pre, ul,ol, li, dl, dt, dd, form, a, fieldset, input, th, td{
margin: 0;
padding: 0;
border: 0;
outline: none;
}

body{
background:#eaeaea none repeat scroll 0 0;
text-align: center;
font-family:"Helvetica Neue",Arial,Helvetica,sans-serif;
font-size:11.5px;
line-height:21px;
}

h1, h2, h3, h4, h5, h6{
font-size: 100%;
margin: 0 15px;
font-weight:normal;
line-height:1.4em;
padding-bottom:5px;
}
ul, ol{
list-style-image: none;
list-style-type: none;
}
img{
border: 0;
}
h1, h2, h3 {
font-weight:normal;
margin:0;
padding:0;
}
h1 {
font-size:32px;
font-weight:normal;
line-height:1.4em;
padding-bottom:0.7em;
color: #3D3D3D;
text-align: center;
border-bottom:1px solid #EEEEEE;
}
h2 {
clear:both;
font-size:18px;
color:#5B5A5A;
line-height:1.4em;
padding-bottom:5px;
}
ul {
margin:0 1.5em 1.5em;
list-style-position:inside;
list-style-type:disc;
}
ol {
list-style-image:none;
list-style-position:inside;
list-style-type:upper-alpha;
}
li {
border-bottom:1px solid #DDDDDD;
padding:3px 10px;
color:#666666;
}
ul.errors li {
color:#CC0000;
}
p{
padding:0 0 1em;
}
hr {
background:#DDDDDD none repeat scroll 0 0;
border:medium none;
clear:both;
color:#DDDDDD;
float:none;
height:0.1em;
margin:0 0 1.45em;
width:100%;
}
a:link, a:visited, a:active{
color:#3366CC;
text-decoration:underline;
}
a:hover {
color:#CC3333;
}

.default {
padding-top: 5px;
padding-right: 10px;
padding-bottom: 5px;
padding-left: 10px;
margin-bottom: 5px;
margin-top: 0px;
margin-right: 0px;
margin-left: 0px;
background-color: #F2F2F2;
border: 1px solid #CCC;
color: #666;
}
.quiet {
color:#666666;
}
.small {
font-size:0.85em;
line-height:1.875em;
margin-bottom:1.875em;
}
#globalinfo{
border-right:1px solid #EEEEEE;
float: left;
width: 180px;
padding: 10px;
font-weight: bold;
}
#globaldescription{
float: right;
width: 410px;
padding: 10px;
}
#wrapper{
width: 700px;
margin: 20px auto;
text-align: left;
}
#header{
height: 130px;
}
#maincontent{
border:1px solid #dddddd;
background-color: #FFF;
padding: 30px;
}
#header h1 {
font-size:24px;
margin:0 0 0 5px;
color:#616263;
}
#header p{
margin:0px 0px 10px 0px;
}
#header ul{
margin: 0px;
padding: 0px;
}
#header li{
list-style: none;
margin: 0px;
padding:0px;
}

#header h1 a {
color:#616263;
text-decoration:none;
}
#header h1 a:hover {
text-decoration: underline;
}
#header .content{
float: right;
width: 550px;
line-height:25px;

}
#header img {
float:left;
margin-right:10px;
}
#header h1 span {
display:inline;
}
#shadow{
height: 13px;
background-color: #EFEFEF;
background-image: url(../media/layout/shadow.gif);
}
#footer{
margin-top: 5px;
color: #898989;
}
#tabbody{
background-image: url(../media/layout/tabbg.png);
background-repeat: repeat-x;
padding: 10px;
margin-top: 0px;
margin-right: 0px;
margin-bottom: 20px;
margin-left: 0px;
}
.bigtext{
font-size: 24px;
text-align: center;
color: #1C4E7E;
font-weight: bold;
}
.red{
color: #FF4411;
}
label{
font-size:14px;
font-weight:bold;
float: left;
width: 205px;
}
textarea{
width: 380px;
}
input, select, textarea{
padding: 4px 6px;
border: solid 1px #7f9db9;
}
.nodisplay{
display: none;
}
.grayed{
background-color: #ebebe4;
color: #aca899;
}
.left{
float: left;
}
.right{
float: right;
}
.spacer{
display: block;
clear: both;
}
.infoline{
padding: 5px;
border-bottom: solid 1px #d4e2ea;
}

.infoblock{
padding: 5px;
border: solid 1px #d4e2ea;
}
.ajaximageholder{
border: solid 1px #eeede0;
background-image: url(../media/layout/load.gif);
background-repeat: no-repeat;
background-position: center center;
margin: 10px 0px;
}
.inputajax{
background-image: url(../media/layout/load.gif);
background-repeat: no-repeat;
background-position: right center;
}
.inputinfo{
font-style:italic;
color:#171717;
font-size: 10px;
}

.normal table, .disabled table, .good table, .bad table{
border: none;
}
.normal table, .disabled table, .good table, .bad table{
font-size:11px;
}

.normal{
background-color: #f4f8fa;
border: solid 1px #d4e2ea;
margin-bottom: 5px;
}
.disabled{
background-color: #f2f2f2;
border: solid 1px #e2e2e2;
margin-bottom: 5px;
color: #bbb;
}
.good{
background-color: #d1f39c;
border: solid 1px #aadc63;
margin-bottom: 5px;
}
.bad{
background-color: #fcc9c9;
border: solid 1px #dc6363;
margin-bottom: 5px;
}
.ajaxholder{
background-image: url(../media/layout/load.gif);
background-repeat: no-repeat;
background-position: center center;
height: 100px;
}
#topbanner{
background-color: #222222;
height: 60px;
text-align:center;
}
#topbanner .content{
width: 700px;
margin: 0px auto;
position:relative;
text-align: left;
font-size:30px;
color: #FFF;
}
#topbanner #topmenu{
position: absolute;
bottom: 0px;
right: 0px;
width: 310px;
height: 36px;
}
#topmenu a:hover {
text-decoration:underline;
}
#topmenu li{
list-style: none;
margin: 0px 0px 0px 5px;
padding: 0px;
float: left;
}
#topmenu a {
color:#FFFFFF;
text-decoration:none;
font-size: 16px;
display: block;
padding: 2px 10px 10px 10px;
}
#topmenu li.active {
background-image: url(../media/layout/arrow.gif);
background-repeat: no-repeat;
background-position: bottom center;
}

.toolblock{
position: relative;
width: 305px;
height: 80px;
background-color: #f4f8fa;
border: solid 1px #d4e2ea;
margin: 5px;
float: left;
}
.toolblockhover{
position: relative;
width: 305px;
height: 80px;
background-color: #E4EEF3;
border: 1px solid #CADBE6;
margin: 5px;
float: left;
}
.toolblock img, .toolblockhover img{
position: absolute;
left: 30px;
top: 19px;
}
.toolblock h3, .toolblockhover h3{
position: absolute;
left: 55px;
top: 15px;
margin: 0px;
padding: 0px;
font-size: 16px;
font-weight:bold;
}
.toolblock span, .toolblockhover span{
position: absolute;
left: 30px;
top: 40px;
font-size: 12px;
}

.new{
position: absolute;
top: 0px;
right: 0px;
background-image: url(../media/layout/new.png);
background-repeat: no-repeat;
width: 34px;
height: 34px;
}

.code{
padding-left: 10px;
border-left: solid 3px #999;
font-family:"Times New Roman", Times, serif;
color:#333;
font-size: 12px;
}
fieldset{
border:1px solid #EEE;
padding: 10px;
margin-bottom: 10px;
}
legend{
color: #BBB;
font-size: 12px;
font-weight: bold;
padding: 5px;
}
-->
</style>
<script type="text/javascript" language="javascript">
function expire(bool){
if(bool){
document.getElementById("txtexpiredate").disabled = "";
document.getElementById("txtexpiremessage").disabled = "";
}else{
document.getElementById("txtexpiredate").disabled = "disabled";
document.getElementById("txtexpiremessage").disabled = "disabled";
}
}
function validhost(bool){
if(bool){
document.getElementById("txtvalidhosts").disabled = "";
document.getElementById("txtvalidhostsmessage").disabled = "";
}else{
document.getElementById("txtvalidhosts").disabled = "disabled";
document.getElementById("txtvalidhostsmessage").disabled = "disabled";
}
}
</script>
</head><body>
<div id="wrapper">
<div id="maincontent">
<h1>ByteScrambler Tool</h1>
<div id="globalinfo">Created: 02/09/2009<br />
Leaked By: <a href="2">niez</a><br />
Email:-leakd</div>
<div id="globaldescription">Thank you for purchasing my script. If you have any questions that are beyond the scope of this help file, please feel free to email via my user page contact form <a href="http://themeforest.net/user/sitebase">here</a>. Thanks so much!</div>
<hr />
<?php if(count($errors) > 0){ ?>
<ul class="errors">
<?php foreach($errors as $error){ ?>
<li><?php echo $error; ?></li>
<?php } ?>
</ul>
<?php } ?>
<form id="form1" name="form1" method="post" action="">
<fieldset>
<legend>Comment</legend>
<p><label for="txtcomment">Script comment</label>
<input name="txtcomment" type="text" id="txtcomment" value="<?php echo $comment; ?>" size="45" />
</p>
</fieldset>
<fieldset>
<legend>Expire Options</legend>
<p>
<label for="chkexpire">Eneable expire options</label>
<input onchange="javascript:expire(this.checked);" name="chkexpire" <?php if($_POST['chkexpire'] == "true") echo 'checked="checked"'; ?> type="checkbox" value="true" />
</p>
<p><label for="txtexpiredate">Expire date</label>
<input name="txtexpiredate" type="text" id="txtexpiredate" value="<?php echo $expiredate; ?>" size="20" <?php if($_POST['chkexpire'] != "true") echo 'disabled="disabled"'; ?> />
</p>
<p><label for="txtexpiremessage">Expire date message</label>
<input name="txtexpiremessage" type="text" id="txtexpiremessage" value="<?php echo $expiremessage; ?>" size="45" <?php if($_POST['chkexpire'] != "true") echo 'disabled="disabled"'; ?> />
</p>
</fieldset>
<fieldset>
<legend>Host Options</legend>
<p>
<label for="chkvalidhosts">Eneable host options</label>
<input onchange="javascript:validhost(this.checked);" <?php if($_POST['chkvalidhosts'] == "true") echo 'checked="checked"'; ?> name="chkvalidhosts" type="checkbox" value="true" />
</p>
<p>
<label for="txtvalidhosts">Valid hosts</label>
<input name="txtvalidhosts" type="text" id="txtvalidhosts" value="<?php echo $validhosts; ?>" size="45" <?php if($_POST['chkvalidhosts'] != "true") echo 'disabled="disabled"'; ?> />
</p>
<p>
<label for="txtvalidhostsmessage">Invalid host message</label>
<input name="txtvalidhostsmessage" type="text" id="txtvalidhostsmessage" value="<?php echo $validhostsmessage; ?>" size="45" <?php if($_POST['chkvalidhosts'] != "true") echo 'disabled="disabled"'; ?> />
</p>
</fieldset>
<fieldset>
<legend>The Script</legend>
<p>
<label for="txtresult">PHP Script</label>
<textarea name="txtscript" id="txtscript" cols="45" rows="15"><?php echo htmlspecialchars($script); ?></textarea>
</p>
<p>
<label for="btnstart">Start encoding</label>
<input type="submit" name="btnstart" id="btnstart" value="Encode Script" />
</p>

<p>
<label for="txtresult">Encoded Script</label>
<textarea name="txtresult" id="txtresult" cols="45" disabled="disabled" rows="15"><?php echo $encoded; ?></textarea>
</p>
<p>
<label for="btnsave">Save this script to file</label>
<input name="btnsave" type="submit" id="btnsave" value="Save Script" />
</p>
</fieldset>
</form>
</div>
</div>
</body></html>

RE: CodeCanyon- ByteScrambler

Trustmaster
Closed Account
Level:
0
Reputation:
0
Posts:
3
Likes:
0
Credits:
0
20-05-2017, 12:41 AM
#2
Looks good, thanks for the share.

RE: CodeCanyon- ByteScrambler

zakirhunter
Closed Account
Level:
0
Reputation:
0
Posts:
15
Likes:
1
Credits:
0
20-05-2017, 05:21 PM
#3
oh no i didnt get any thing

RE: CodeCanyon- ByteScrambler

amricow
Lurker
Level:
0
Reputation:
0
Posts:
2
Likes:
0
Credits:
3
10-07-2017, 09:36 PM
#4
old seller on codecanyon, seller doesnt support
last update 2011

RE: CodeCanyon- ByteScrambler

Venipa
venipa.net
Level:
6
Reputation:
91
Posts:
525
Likes:
148
Credits:
6.18K
10-07-2017, 10:25 PM
#5
Thats sum Quality Thread.
/au4to0][Image: ad0png.png]
[Image: view?username=Venipa&style=small]

RE: CodeCanyon- ByteScrambler

gh0stl4b
Newbie
Level:
0
Reputation:
0
Posts:
15
Likes:
0
Credits:
64
12-07-2017, 10:30 AM
#6
Why not just upload an archive of this code and share the link?

RE: CodeCanyon- ByteScrambler

onnuurr
Closed Account
Level:
0
Reputation:
0
Posts:
4
Likes:
0
Credits:
8
03-04-2018, 11:29 PM
#7
Thank you. It's a good idea. It's a lot of work.https://nulledbb.com

RE: CodeCanyon- ByteScrambler

lintahdarat
Novice
Level:
0
Reputation:
0
Posts:
25
Likes:
4
Credits:
32
10-04-2018, 01:50 AM
#8
It's just scrambling or obfuscate the code, not protect it. For commercial use, I suggest to use IonCube or Zend.
Crown your feet with honor and behold.

RE: CodeCanyon- ByteScrambler

WhySpice
Newbie
Level:
0
Reputation:
0
Posts:
15
Likes:
0
Credits:
30
20-04-2018, 05:58 PM
#9
Hhh, nice leak. I hope it will come in handy, maybe I'll take it for my projects

Users browsing this thread: 1 Guest(s)