Go Back   RunUO - Ultima Online Emulation > Developer's Corner > Programming > Script Languages

Script Languages Perl/PHP/Python/Ruby so on and so forth.

Reply
 
Thread Tools Display Modes
Old 02-01-2007, 10:45 PM   #1 (permalink)
Forum Expert
 
FingersMcSteal's Avatar
 
Join Date: Mar 2006
Location: North East, England, UK
Posts: 856
Send a message via ICQ to FingersMcSteal Send a message via MSN to FingersMcSteal
Default Totally stuck on this PHP code

The full release of this originally came from the forums here. I'm new to php and manipulating data within the MUL files, so i need loads of help understanding what this code does exactly... in other words, stumpped

This is the PHP file to generate a paper doll image for a web page and i'm stuffed if i can get the damn thing to work, i've highlighted the parts in red where i need help understanding what it's doing or not doing in my case.

I'll attach the full zipped release as well, i cant contact the original creator so need a little help... thanks in advance.

The paperdoll.php file...

PHP Code:
<?php
/*
    The paperdoll generator is based on GumpReader PHP by Kinetix <webmaster@ikrontik.tk>.
    The below copyright information applies to his portions of this script.
*/

/*
* GumpReader PHP 1.1.0
* Author: Kinetix <webmaster@ikrontik.tk>
*
* This has been directly translated from my C program that does the exact same thing. So excuse the messiness.
*
* IF YOU REDISTRIBUTE THIS FILE WITHIN ANOTHER PACKAGE (such as MyUO), YOU MUST FIRST HAVE MY PERMISSION
* AND MUST GIVE ME CREDIT WHERE IT IS DUE! Do _not_ claim someone else's work for yourself.
*
* Released under The MIT License
    Copyright (c) 2004 Kinetix
    Permission is hereby granted, free of charge, to any person obtaining a copy of this
      software and associated documentation files (the "Software"), to deal in the Software
      without restriction, including without limitation the rights to use, copy, modify, merge,
      publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
      to whom the Software is furnished to do so, subject to the following conditions:
    All copyright notices and this permission notice shall be included in all copies or substantial
      portions of the Software and must remain unmodified.
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
      BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
      NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
      DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

require("myrunuo.inc.php");

check_get($id"id");
$id intval($id);
if (!
$id)
  die();

if (!empty(
$validhosts)) {
  if (isset(
$_SERVER["HTTP_REFERER"]))
    
$ref strtolower($_SERVER["HTTP_REFERER"]);
  else
    
$ref "";   
  
$validhosts strtolower($validhosts);
  
$vhosts explode(" "$validhosts);
  
$host 0;
  
$valid false;
  while (isset(
$vhosts[$host]) && !$valid) {
      if (
substr($ref0strlen($vhosts[$host])) == $vhosts[$host])
        
$valid true;
      
$host++;
  }
  if (!
$valid)
    die();
}

$link sql_connect();
$result sql_query($link"SELECT char_nototitle,char_female,char_bodyhue FROM myrunuo_characters WHERE char_id=$id");
if (!(list(
$nametitle,$charfemale,$charbodyhue) = mysql_fetch_row($result)))
  die();
mysql_free_result($result);

// Insert body into variables
if ($charfemale) {
  
$indexA "13";
  
$femaleA "1";
}
else {
  
$indexA "12";
  
$femaleA "0";
}
$hueA $charbodyhue;
$isgumpA "1";

$result sql_query($link"SELECT item_id,item_hue,layer_id FROM myrunuo_characters_layers WHERE char_id=$id ORDER BY layer_id");
$items = array(array());
$num $dosort 0;
while (
$row mysql_fetch_row($result)) {
  
$items[0][$num] = $row[0];
  
$items[1][$num] = $row[1];
  if (
$row[2] == 13) {
    
$items[2][$num++] = 3.5// Fix for tunic
    
$dosort 1;
  }
  else
      
$items[2][$num++] = $row[2];
}
mysql_free_result($result);
mysql_close($link);

if (
$dosort)
  
array_multisort($items[2], SORT_ASCSORT_NUMERIC$items[0], SORT_ASCSORT_NUMERIC$items[1], SORT_ASCSORT_NUMERIC);

for (
$i 0$i $num$i++) {
  
// Insert items into variables
  
$indexA .= ",".$items[0][$i];
  
$hueA .= ",".$items[1][$i];
  if (
$charfemale)
    
$femaleA .= ",1";
  else
    
$femaleA .= ",0";
  
$isgumpA .= ",0";
}

[
color="Red"]// Paperdoll Graphic Area **** FROM HERE **** Red tags didnt work !!!
$width 182;
$height 237;

if (
strpos($indexA",")) {
  
$indexA explode(","$indexA);
  
$femaleA explode(","$femaleA);
  
$hueA explode(","$hueA);
  
$isgumpA explode(","$isgumpA);
}
else {
  
$indexA = array($indexA);
  
$femaleA = array($femaleA);
  
$hueA = array($hueA);
  
$isgumpA = array($isgumpA);
}

$hues FALSE;
$tiledata FALSE;
$gumpfile FALSE;
$gumpindex FALSE;

$hues fopen("{$mulpath}hues.mul""rb");
if (
$hues == FALSE)
{
  die(
"Unable to open hues.mul - ERROR\nDATAEND!");
  exit;
}

$tiledata fopen("{$mulpath}Tiledata.mul""rb");
if (
$tiledata == FALSE)
{
  
fclose($hues);
  die(
"Unable to open tiledata.mul - ERROR\nDATAEND!");
  exit;
}

$gumpfile fopen("{$mulpath}gumpart.mul""rb");
if (
$gumpfile == FALSE)
{
  
fclose($hues);
  
fclose($tiledata);
  die(
"Unable to open gumpart.mul - ERROR\nDATAEND!");
  exit;
}

$gumpindex fopen("{$mulpath}gumpidx.mul""rb");
if (
$gumpindex == FALSE)
{
  
fclose($hues);
  
fclose($tiledata);
  
fclose($gumpfile);
  die(
"Unable to open gumpidx.mul - ERROR\nDATAEND!");
  exit;
}

InitializeGump($gumprawdata$width$height);
for (
$i 0$i sizeof($indexA); $i++)
{
  
$index intval($indexA[$i]);
  
$female intval($femaleA[$i]);
  
$hue intval($hueA[$i]);
  
$isgump intval($isgumpA[$i]);

  if (
$female >= 1)
    
$female 1;
  else
    
$female 0;

  if (
$hue || $hue 65535)
    
$hue 0;

  if(
$isgump || $index == 12 || $index == 13)
    
$isgump 1;
  else
    
$isgump 0;

  if (
$index 0x3FFF || $index <= || $hue 65535 || $hue 0)
    continue;

  if (
$isgump == 1// Male/Female Gumps or IsGump Param
    
$gumpid $index;
  else {
    
$group intval($index 32);
    
$groupidx $index 32;
    
fseek($tiledata512 836 1188 $group $groupidx 37SEEK_SET);
    if (
feof($tiledata))
      continue;

    
// Read the flags
    
$flags read_big_to_little_endian($tiledata4);
    if (
$flags == -1)
      continue;

    if (
$flags 0x00400000) {
      
fseek($tiledata6SEEK_CUR);
      
$gumpid read_big_to_little_endian($tiledata2);
      
$gumpid = ($gumpid 0xFFFF);
      if (
$gumpid 65535 || $gumpid <= 0)
        continue; 
// Invalid gump ID

      
if ($gumpid 10000) {
        if (
$female == 1)
          
$gumpid += 60000;
        else
          
$gumpid += 50000;
      }
    }
    else
      continue; 
// Not wearable
  
}
  
LoadRawGump($gumpindex$gumpfileintval($gumpid), $hue$hues$gumprawdata);
}

// Separate name and skill title
$nametitle striphtmlchars($nametitle);
if ((
$i strpos($nametitle",")) !== FALSE) {
    
$name substr($nametitle0$i);
  
$title substr($nametitle$i 2);
}
else {
    
$name $nametitle;
    
$title "";
}

AddText($gumprawdata$name$title);
CreateGump($gumprawdata);
fclose($hues);
fclose($tiledata);
fclose($gumpfile);
fclose($gumpindex);
exit;

function 
LoadRawGump($gumpindex$gumpfile$index$hue$hues, &$gumprawdata)
{
  
$send_data '';
  
$color32 = array();

  
fseek($gumpindex$index 12SEEK_SET);
  if (
feof($gumpindex))
    return; 
// Invalid gumpid, reached end of gumpindex.

  
$lookup read_big_to_little_endian($gumpindex4);
  if (
$lookup == -1) {
    if (
$index >= 60000)
      
$index -= 10000;
    
fseek($gumpindex$index 12SEEK_SET);
    if (
feof($gumpindex)) // Invalid gumpid, reached end of gumpindex.
      
return;
    
$lookup read_big_to_little_endian($gumpindex4);
    if (
$lookup == -1)
      return; 
// Gumpindex returned invalid lookup.
  
}
  
$gsize read_big_to_little_endian($gumpindex4);
  
$gextra read_big_to_little_endian($gumpindex4);
  
fseek($gumpindex$index 12SEEK_SET);
  
$gwidth = (($gextra >> 16) & 0xFFFF);
  
$gheight = ($gextra 0xFFFF);
  
$send_data .= sprintf("Lookup: %d\n"$lookup);
  
$send_data .= sprintf("Size: %d\n"$gsize);
  
$send_data .= sprintf("Height: %d\n"$gheight);
  
$send_data .= sprintf("Width: %d\n"$gwidth);

  if (
$gheight <= || $gwidth <= 0)
    return; 
// Gump width or height was less than 0.

  
fseek($gumpfile$lookupSEEK_SET);
  
$heightTable read_big_to_little_endian($gumpfile, ($gheight 4));
  if (
feof($gumpfile))
    return; 
// Invalid gumpid, reached end of gumpfile.

  
$send_data .= sprintf("DATASTART:\n");
  if (
$hue <= 0) {
    for (
$y 1$y $gheight$y++) {
      
fseek($gumpfile$heightTable[$y] * $lookupSEEK_SET);

      
// Start of row
      
$x 0;
      while (
$x $gwidth) {
        
$rle read_big_to_little_endian($gumpfile4);  // Read the RLE data
        
$length = ($rle >> 16) & 0xFFFF;  // First two bytes - how many pixels does this color cover
        
$color $rle 0xFFFF;  // Second two bytes - what color do we apply

        // Begin RGB value decoding
        
$r = (($color >> 10)*8);
        
$g = (($color >> 5) & 0x1F)*8;
        
$b = ($color 0x1F)*8;
        if (
$r || $g || $b 0)
          
$send_data .= sprintf("%d:%d:%d:%d:%d:%d***"$x$y$r$g$b$length);
        
$x $x $length;
      }
    }
  }
  else { 
// We are using the hues.mul
    
$hue $hue 1;
    
$orighue $hue;
    if (
$hue 0x8000)
      
$hue $hue 0x8000;
    if (
$hue 3001// Bad hue will cause a crash
      
$hue 1;
    
$colors intval($hue 8) * 4;
    
$colors $hue 88 $colors;
    
fseek($hues$colorsSEEK_SET);
    for (
$i 0$i 32$i++) {
      
$color32[$i] = read_big_to_little_endian($hues2);
      
$color32[$i] |= 0x8000;
    }
    for (
$y 1$y $gheight$y++) {
      
fseek($gumpfile$heightTable[$y] * $lookupSEEK_SET);

      
// Start of row
      
$x 0;
      while (
$x $gwidth) {
        
$rle read_big_to_little_endian($gumpfile4);  // Read the RLE data
        
$length = ($rle >> 16) & 0xFFFF;  // First two bytes - how many pixels does this color cover
        
$color $rle 0xFFFF;  // Second two bytes - what color do we apply

        // Begin RGB value decoding
        
$r = (($color >> 10));
        
$g = (($color >> 5) & 0x1F);
        
$b = ($color 0x1F);

        
// Check if we're applying a special hue (skin hues), if so, apply only to grays
        
if (($orighue 0x8000) && ($r == $g && $r == $b)) {
          
$newr = (($color32[$r] >> 10))*8;
          
$newg = (($color32[$r] >> 5) & 0x1F)*8;
          
$newb = ($color32[$r] & 0x1F)*8;
        }
        else if (
$orighue 0x8000) {
          
$newr $r 8;
          
$newg $g 8;
          
$newb $b 8;
        }
        else {
          
$newr = (($color32[$r] >> 10))*8;
          
$newg = (($color32[$r] >> 5) & 0x1F)*8;
          
$newb = ($color32[$r] & 0x1F)*8;
        }
        if(((
$r 8) > 0) || (($g 8) > 0) || (($b 8) > 0))
          
$send_data .= sprintf("%d:%d:%d:%d:%d:%d***"$x $y$newr$newg$newb$length);
        
$x += $length;
      }
    }
  }
  
$send_data .= sprintf("DATAEND!");
  
add_gump($send_data$gumprawdata);
}

function 
read_big_to_little_endian($file$length)
{
  if ((
$val fread($file$length)) == FALSE)
    return -
1;

  switch(
$length)
  {
    case 
4$val unpack('l'$val); break;
    case 
2$val unpack('s'$val); break;
    case 
1$val unpack('c'$val); break;
    default: 
$val unpack('l*'$val); return $val;
  }
  return (
$val[1]);
}

function 
add_gump($read, &$img)
{
  if (
strpos($read"ERROR"))
    return;

  
$data explode("DATASTART:\n"$read);
  
$data $data[1];
  
$newdata explode("***"$data);
  while (list(
$key$val) = @each($newdata)) {
    if (
$val == "DATAEND!")
      break;
    
$val explode(":"$val);
    
$x intval($val[0]) + 8;
    
$y intval($val[1]) + 15;
    
$r intval($val[2]);
    
$g intval($val[3]);
    
$b intval($val[4]);
    
$length intval($val[5]); // pixel color repeat length
    
if ($r || $g || $b) {
      
$col imagecolorallocate($img$r$g$b);
      for (
$i 0$i $length$i++)
        
imagesetpixel($img$x+$i$y$col);
    }
  }
}

function 
InitializeGump(&$img$width$height)
{
  
$img imagecreatefrompng("images/paperdoll.png") or die("couldnt create image");
  
imagealphablending($imgTRUE);
}[/
color] ******** TO ABOUT HERE ********* Red end tag didnt work :)
function 
AddText(&$img$name$title)
{
    
$textcolor imagecolorallocate($img000);
    
$pos = (int) (131 - (strlen($name) * 3.5));
    if (
$pos 0)
      
$pos 0;
  
imagestring($img3$pos266$name$textcolor); // 35, 266
    
$pos = (int) (131 - (strlen($title) * 3.5));
    if (
$pos 0)
      
$pos 0;
  
imagestring($img3$pos283$title$textcolor); // 35, 283
}

function 
CreateGump(&$img)
{
  
Header("Content-type: image/png");
  
imagepng($img);
  
imagedestroy($img);
}

function 
striphtmlchars($str)
{
  
$nstr str_replace("&amp;""&"$str);
  
$nstr str_replace("'""'"$nstr);
  return 
$nstr;
}

?>
Basically i'm getting a blank web page with no errors or image, not even the PNG image with this release.
Attached Files
File Type: zip MyRunUO-PHP-1.01.zip (60.1 KB, 23 views)
FingersMcSteal is offline   Reply With Quote
Old 06-23-2007, 02:06 AM   #2 (permalink)
Forum Novice
 
Join Date: Oct 2005
Posts: 142
Default

I'm not terribly fluent in PHP, but I'll help with what I know. If it's a bit off and someone more experienced comes in, it's probably better to listen to this. There may be technicalities I'm off on, but the general idea will hopefully set you on the right path. Keep in mind, I'm not really able to investigate the code thoroughly tonight, so I'm just doing a line-by-line analysis.

require("myrunuo.inc.php");
The require function forces another script to run and be completed before the script continues. For instance, if I want to force the user to input their name and password before viewing the page, I can make a simple login script and put a require("login.php); at the top of the page.

check_get($id, "id");
I didn't see a check_get(); function listing in the PHP function list, so I'm guessing that it's a function designed by whomever wrote the code. It looks like some kind of identification they're retrieving from another page. Based on this line - $id = intval($id); -, we at least know they want an integer value as the ID.

if (isset($_SERVER["HTTP_REFERER"]))
isset() checks to see if a variable has been set to something. For instance:
a = 2; <-- a is set here
isset(a); <-- This would return True, because a is set.
isset(b); <-- This would return False, because b is not set.
<--Not too sure about this one, never had to use isset(), so that may not be the proper usage-->
So based on that, it looks like it's checking to see if the site that you're coming from, or the HTTP_REFERER, is 'set' in the $_SERVER array. I might be totally off here, but that looks about right.

$result = sql_query($link, "SELECT char_nototitle,char_female,char_bodyhue FROM myrunuo_characters WHERE char_id=$id");
This is just an SQL query. If you haven't worked with a SQL database before, it can look really scary. However, it's really not so bad. Basically, this code is selecting the several rows from a table in a database where their char_id is the $id variable. This is where the ID from earlier is being used.

It's kind of late, and I don't really have the time tonight to go over the rest of the code. I skimmed over it, and at least one thing I can address really quickly is where you marked a lot of die() functions in red.

die(); just kills the script and optionally displays a message.

Think about coding like this:
if(true)
{
do a block of code;
}

When a ! is in front of a statement, it takes the opposite.

!true is false.
!false is true.
See?

If we write-
if(!true)
{
die("There was an error!");
}
-we are somewhat effectively error trapping.

Hopefully this will clear a few things up for you.
For future reference, many functions can be found at PHP.net, in the documentation section. Also, don't be afraid to use Google search if you don't understand something.

Hearing it from people is often easier to understand, but you must remember that it takes a good amount of time for people to read through and explain every detail in code.
Shadow-Sigma is offline   Reply With Quote
Old 08-01-2007, 04:02 PM   #3 (permalink)
Newbie
 
Join Date: Oct 2004
Location: Charleston, SC
Age: 27
Posts: 37
Send a message via ICQ to LightShade Send a message via AIM to LightShade
Default

What errors are you getting? Do you have the appropriate PHP modules setup? Perhaps GD2? I'm not sure, lemme know what errors you're getting.
LightShade is offline   Reply With Quote
Old 07-01-2008, 02:59 AM   #4 (permalink)
Account Terminated
 
Join Date: Jul 2006
Age: 29
Posts: 240
Default

first you need a MySQL server running, with ODBC 3.5 drivers installed on your web server machines. it is best to run your RunUO server on your MySQL/Webserver. once you have all this.. you need to build your SQL database for MyRunUO, with the SQL text file in your zip.. once this is done make sure your config file is set up correctly.. then your MyRunUO config file is enabled and set up correctly.

someone else asked me about this earlier ill write up a step by step guide to what you need to do some time later this week, maybe next.. I am still working on learning php scripting myself.. finding it very intersting.

heres the end result when you get done.. both images are generated through that script. with some modifications. I made the black version first for my site and decided to make a white alternate if player want to use it on other websites.



.. just reread your post.. remember you cannot call the paperdoll.php directly.. its a script that is called through the player.php script.. and the player.php is called through from the Status.php which builds a list of player ids.... so you can see the player(.php)s. which in turn has the paperdoll image built through it.. once you have the paperdoll. you can copy the image src and post it else where if you want.

Last edited by Zaphieon; 07-01-2008 at 03:07 AM.
Zaphieon is offline   Reply With Quote
Reply

Bookmarks