Last active
August 29, 2015 14:06
-
-
Save mbasaglia/1fc40743fd7bdf3151a0 to your computer and use it in GitHub Desktop.
PHP script for colorful Xonotic Chat
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* \file | |
* \brief Simple web script to get colorful text in Xonotic | |
* \par Basic Usage | |
* \code menu_cmd qc_curl --exec http://localhost/this_script.php cmd echo c1 000 c2 fff text "Hello world" \endcode | |
* \par Example with aliases | |
\code | |
set mb_net_chat_server "http://localhost/xonchat/index.php" | |
alias mb_net_chat "menu_cmd qc_curl --exec $mb_net_chat_server cmd \"$1\" c1 $2 c2 $3 text \"$mb_net_str\"" | |
alias mb_net_say "set mb_net_str \"${3- q}\"; mb_net_chat say $1 $2" | |
alias mb_net_echo "set mb_net_str \"${3- q}\"; mb_net_chat echo $1 $2" | |
alias mb_net_rainbow_chat "menu_cmd qc_curl --exec $mb_net_chat_server cmd \"$1\" text \"$mb_net_str\"" | |
alias mb_net_rainbow_say "set mb_net_str \"${* q}\"; mb_net_rainbow_chat say" | |
alias mb_net_rainbow_echo "set mb_net_str \"${* q}\"; mb_net_rainbow_chat echo" | |
\endcode | |
*/ | |
/** | |
* \brief Simple, 12 bit rgb color | |
*/ | |
class Color | |
{ | |
public $r, $g, $b; | |
function __construct ($r=0, $g=0, $b=0) | |
{ | |
$this->r = $r; | |
$this->g = $g; | |
$this->b = $b; | |
} | |
/** | |
* \brief Get the 12bit integer | |
*/ | |
function bitmask() | |
{ | |
return ($this->r<<8)|($this->g<<4)|$this->b; | |
} | |
/** | |
* \brief Encode to darkplaces | |
*/ | |
function encode() | |
{ | |
/*switch ( $this->bitmask() ) | |
{ | |
case 0x000: return "^0"; | |
case 0xf00: return "^1"; | |
case 0x0f0: return "^2"; | |
case 0xff0: return "^3"; | |
case 0x00f: return "^4"; | |
case 0xf0f: return "^6"; | |
case 0x0ff: return "^5"; | |
case 0xfff: return "^7"; | |
}*/ | |
return "^x".dechex($this->r).dechex($this->g).dechex($this->b); | |
} | |
/** | |
* \brief Decode darkplaces color | |
*/ | |
static function decode($dpcolor) | |
{ | |
$dpcolor = ltrim($dpcolor,"^x"); | |
if ( strlen($dpcolor) == 3 ) | |
return new Color(hexdec($dpcolor[0]),hexdec($dpcolor[1]),hexdec($dpcolor[2])); | |
else if ( strlen($dpcolor) == 1 ) | |
switch ( $dpcolor[0]) | |
{ | |
case 0: return new Color(0,0,0); | |
case 1: return new Color(0xf,0,0); | |
case 2: return new Color(0,0xf,0); | |
case 3: return new Color(0xf,0xf,0); | |
case 4: return new Color(0,0,0xf); | |
case 5: return new Color(0,0xf,0xf); | |
case 6: return new Color(0xf,0,0xf); | |
case 7: return new Color(0xf,0xf,0xf); | |
case 8: | |
case 9: return new Color(0x8,0x8,0x8); | |
} | |
return new Color(); | |
} | |
/** | |
* \brief Blend two colors together | |
* \param $c1 First color | |
* \param $c2 Second color | |
* \param $factor Blend factor 0 => \c $c1, 1 => \c $c2 | |
*/ | |
static function blend(Color $c1, Color $c2, $factor) | |
{ | |
return new Color(round($c1->r*(1-$factor) + $c2->r*$factor), | |
round($c1->g*(1-$factor) + $c2->g*$factor), | |
round($c1->b*(1-$factor) + $c2->b*$factor)); | |
} | |
/** | |
* \brief Get a color from HSV components in [0,1] | |
*/ | |
static function from_hsv($h,$s,$v) | |
{ | |
$h *= 6; | |
$c = $v*$s; | |
$m = $v-$c; | |
$h1 = floor($h); | |
$f = $h - $h1; | |
$n = $v - $c * $f; | |
$k = $v - $c * (1 - $f); | |
$v = round($v*0xf); | |
$m = round($m*0xf); | |
$n = round($n*0xf); | |
$k = round($k*0xf); | |
switch ($h1) | |
{ | |
case 0: return new Color($v,$k,$m); | |
case 1: return new Color($n,$v,$m); | |
case 2: return new Color($m,$v,$k); | |
case 3: return new Color($m,$n,$v); | |
case 4: return new Color($k,$m,$v); | |
case 6: | |
case 5: return new Color($v,$m,$n); | |
} | |
return new Color(); | |
} | |
} | |
class Char | |
{ | |
public $char, $color; | |
function __construct($char, $color=null) | |
{ | |
$this->char = $char; | |
$this->color = $color; | |
} | |
} | |
header("Content-Type: text/plain"); | |
$color1 = Color::decode( isset($_REQUEST["c1"]) ? $_REQUEST["c1"] : "0" ); | |
$color2 = Color::decode( isset($_REQUEST["c2"]) ? $_REQUEST["c2"] : "7" ); | |
$rainbow = !isset($_REQUEST["c1"]) && !isset($_REQUEST["c2"]); | |
$cmd = isset($_REQUEST["cmd"]) ? $_REQUEST["cmd"] : "echo"; | |
$text = isset($_REQUEST["text"]) ? $_REQUEST["text"] : ""; | |
echo "$cmd "; | |
$text_arr = array(); | |
$multichar = array(); | |
$color = null; | |
for ( $i = 0; $i < strlen($text); $i++ ) | |
{ | |
$c = $text[$i]; | |
$o = ord($c); | |
if ( $o < 128 ) | |
{ | |
if ( $c == "^" && $i+1 < strlen($text)) | |
{ | |
if ( $text[$i+1] == "^" ) | |
{ | |
$i++; // skip second ^ | |
$text_arr []= new Char("^^",$color); // escaped ^^ | |
$color = null; | |
} | |
else if ( ctype_digit($text[$i+1]) ) | |
{ | |
$i++; // skip number | |
$color = Color::decode($text[$i+1]); // ^n color | |
} | |
else if ( $text[$i+1] == 'x' && $i+4 < strlen($text) ) | |
{ | |
$color = Color::decode(substr($text,$i,5)); // ^xHHH color | |
$i+=4; // skip color code | |
} | |
} | |
else | |
{ | |
$text_arr []= new Char($c,$color); | |
$color = null; | |
} | |
} | |
else // multi-byte UTF-8 | |
{ | |
if ( count($multichar) == 0 ) | |
{ | |
$s = ""; | |
$length = ( $o < 224 ) ? 2 : 3; | |
} | |
$multichar[] = $o; | |
$s .= $c; | |
if ( count( $multichar ) == $length ) | |
{ | |
$unicode = ( $length == 3 ) ? | |
( ( $multichar[0] % 16 ) << 12 ) + ( ( $multichar[1] % 64 ) << 6 ) + ( $multichar[2] % 64 ): | |
( ( $multichar[0] % 32 ) << 6 ) + ( $multichar[1] % 64 ); | |
$text_arr []= new Char($s,$color); | |
$color = null; | |
$multichar = array(); | |
} | |
} | |
} | |
for ( $i = 0; $i < count($text_arr); $i++ ) | |
{ | |
if ( $rainbow ) | |
$color = Color::from_hsv($i/count($text_arr),0.75,1); | |
else | |
$color = Color::blend($color1,$color2, $i == 0 ? 0 : $i/(count($text_arr)-1) ); | |
echo $text_arr[$i]->color ? $text_arr[$i]->color->encode() : $color->encode(); | |
echo $text_arr[$i]->char; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment