Skip to content

Instantly share code, notes, and snippets.

@mbasaglia
Last active August 29, 2015 14:06
Show Gist options
  • Save mbasaglia/1fc40743fd7bdf3151a0 to your computer and use it in GitHub Desktop.
Save mbasaglia/1fc40743fd7bdf3151a0 to your computer and use it in GitHub Desktop.
PHP script for colorful Xonotic Chat
<?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