xixi 发表于 2004-5-28 20:03:39

奇怪的AMXX乘法????HELP

我在编写AMXX脚本时(初学),使用AMXX乘法*号时,得出的结果是负数?????
IP地址是 192.168.0.169 代码如下.

new ipcode, ip, ipta, iptb, iptc, iptd
   new ipna, ipnb, ipnc, ipnd, ipnuma, textlen
   get_user_ip(param, ip, 16, 1)
   replace(ip, 16, ".", " ")
   replace(ip, 16, ".", " ")
   replace(ip, 16, ".", " ")
   replace(ip, 16, ".", " ")
   parse(ip, ipta, 3, iptb, 3, iptc, 3, iptd, 3)
   ipna = strtonum(ipta)
   ipnb = strtonum(iptb)
   ipnc = strtonum(iptc)
   ipnd = strtonum(iptd)
   ipnuma = (ipna*256*256*256)+(ipnb*256*256)+(ipnc*256)+ipnd


   client_print(0,print_chat,"ipna: %i ipnb: %i ipnc: %i ipnd: %i ipnuma: %i ", ipna, ipnb, ipnc, ipnd, ipnuma)

结果 ipnuma 的值是 -1062731607 ?!

我用PHP计算的代码如下:


$Ip="192.168.0.169";
$array=explode('.',$Ip);
$Int=($array * 256*256*256) + ($array*256*256) + ($array*256) + $array;
echo $Int;


PHP计算得出的值是 3232235689

AMXX算出来的怎么和PHP差那么多呀,大家帮帮我.看我的AMXX代码要怎么样写才能得出PHP计算的那个值呀???????

xixi 发表于 2004-5-28 22:54:25

AMXX的数值变量长度不能超过10位.一超过就溢出呀.
例:

3657433088

在AMXX里显出来的是

-637534208

smartsl 发表于 2004-5-29 10:24:30

一个256就是0x100,4个就是0x100000000,在32位机器上正好够用。不过SMALL语言里面似乎只有signed类型,所以范围就是
-2147483648~2147483647。

不知道楼主想计算这个干什么?一定可以换一种方法解决。

xixi 发表于 2004-5-29 19:31:40

想用QQ的IP地址文件QQWRY.DAT的数据呀.
要用第一步就是要把IP转换出来呀.

第一个计算都不行,我倒呀...

xixi 发表于 2004-6-2 21:52:53

顶 :cry2::cry2::cry2::cry2:

helloworld 发表于 2004-6-3 12:15:33

client_print(0,print_chat,"ipna: %i ipnb: %i ipnc: %i ipnd: %i ipnuma: %i ", ipna, ipnb, ipnc, ipnd, ipnuma)

换成
client_print(0,print_chat,"ipna: %d ipnb: %d ipnc: %d ipnd: %d ipnuma: %d ", ipna, ipnb, ipnc, ipnd, ipnuma)

xixi 发表于 2004-6-3 21:25:56

不行呀. :10:

helloworld 发表于 2004-6-4 16:32:09

这个是country.sma

/* AMXMOD script.
*
* (c) Copyright 2000-2002, Rich - This file is provided as is (no warranties).
*
* Player Country 1.0 - Converts IP Address to Country Code via a database.
*
* - Must put the country.dat /addons/amx/ folder.
*
* - amx_showcountry 0/1 cvar for turning it on or off.
*
* - Thanks goes to:
*
* http://www.ip-to-country.com/for providing original csv database.
*
* http://amxmod.net/forums/viewtopic.php?t=10117spectating code by ST4life.
*
*/

#include <amxmod>

new filepath = "addons/amx/country.dat"
new country

public plugin_init()
{
register_plugin("Show Country","1.0","Rich")
register_event("StatusValue","show_country","bd","1=2")
register_clcmd("say /country","show_owncountry")
register_cvar("amx_showcountry","1")
}

public client_connect(id)
{
if (!(get_cvar_num("amx_showcountry")))
{
    return PLUGIN_CONTINUE
}

new ipcode, ccode, playerip, ipta, iptb, iptc, iptd, text
new line, ipna, ipnb, ipnc, ipnd, ipnuma, ipnumb, textlen, startline, endline = 32000

get_user_ip(id, playerip, 16, 1)

replace(playerip, 16, ".", " ")
replace(playerip, 16, ".", " ")
replace(playerip, 16, ".", " ")
replace(playerip, 16, ".", " ")

parse(playerip, ipta, 3, iptb, 3, iptc, 3, iptd, 3)

ipna = strtonum(ipta)
ipnb = strtonum(iptb)
ipnc = strtonum(iptc)
ipnd = strtonum(iptd)

//127 for slow/accurate or 60 for fast/approximate

if (ipna > 60)
{
    ipnuma = (ipna * 1677721) + (ipnb * 6553) + ( ipnc * 26 ) + ipnd
}
else
{
    ipnuma = (ipna * 16777216) + (ipnb * 65536) + ( ipnc * 256 ) + ipnd
    numtostr(ipnuma, ipcode, textlen)
    copy(ipcode,9,ipcode)
    ipnuma = strtonum(ipcode)
}

for (new i = 0; i < 16; i++)
{
      line = startline + ((endline - startline) / 2)

      if (i == 15)
      {
      ++line
      }

      read_file(filepath, line, text, 255, textlen)
   
      parse(text, ipcode, 9, ccode, 2)
      ipnumb = strtonum(ipcode)

//Diagnostic:
//client_print(0,print_chat,"Line: %i Start: %i End: %i PlayerCode: %i FileCode: %i", line, startline, endline, ipnuma, ipnumb)

      if (ipnuma > ipnumb)
      {
      startline = line
      }
      else
      {
      endline = line
      }
}

//Show Country on Connect - Only use if you know what your doing:
//client_print(0,print_chat,"Connecting IP: %i - Code: %i File: %i Country: %s", playerip, ipnuma, ipnumb, ccode)

country = ccode

return PLUGIN_CONTINUE
}

public show_country(id)
{
if (!(get_cvar_num("amx_showcountry")))
{
    return PLUGIN_CONTINUE
}

new target = read_data(2)

if (target != id && target != 0)
{
    set_hudmessage(255,255,255,0.02,0.88,0, 0.5, 1.0, 0.0, 0.0, 27)
    show_hudmessage(id,"Country Code: %s",country)
}

return PLUGIN_CONTINUE
}

public show_owncountry(id)
{
client_print(id,print_chat,"Your Country Code: %s",country)
return PLUGIN_HANDLED
}

xixi 发表于 2004-6-5 16:50:13

这个是PHP用QQwry.dat查IP所属地的代码

<?
define('QQWRY' ,'./QQwry.dat' ) ;

function IpToInt($Ip) {
   $array=explode('.',$Ip);
   $Int=($array * 256*256*256) + ($array*256*256) + ($array*256) + $array;
   return $Int;
}

function IntToIp($Int) {
   $b1=($Int & 0xff000000)>>24;
   if ($b1<0) $b1+=0x100;
   $b2=($Int & 0x00ff0000)>>16;
   if ($b2<0) $b2+=0x100;
   $b3=($Int & 0x0000ff00)>>8;
   if ($b3<0) $b3+=0x100;
   $b4= $Int & 0x000000ff;
   if ($b4<0) $b4+=0x100;
   $Ip=$b1.'.'.$b2.'.'.$b3.'.'.$b4;
   return $Ip;
}

class TQQwry
{
   var $StartIP = 0;
   var $EndIP = 0;
   var $Country = '';
   var $Local = '';

   var $CountryFlag = 0; // 标识 Country位置
                         // 0x01,随后3字节为Country偏移,没有Local
                         // 0x02,随后3字节为Country偏移,接着是Local
                         // 其他,Country,Local,Local有类似的压缩。可能多重引用。
   var $fp;

   var $FirstStartIp = 0;
   var $LastStartIp = 0;
   var $EndIpOff = 0 ;

   function getStartIp ( $RecNo ) {
       $offset = $this->FirstStartIp + $RecNo * 7 ;
       @fseek ( $this->fp , $offset , SEEK_SET ) ;
       $buf = fread ( $this->fp , 7 ) ;
       $this->EndIpOff = ord($buf) + (ord($buf)*256) + (ord($buf)* 256*256);
       $this->StartIp = ord($buf) + (ord($buf)*256) + (ord($buf)*256*256) + (ord($buf)*256*256*256);
       return $this->StartIp ;
   }

   function getEndIp ( ) {
       @fseek ( $this->fp , $this->EndIpOff , SEEK_SET ) ;
       $buf = fread ( $this->fp , 5 ) ;
       $this->EndIp = ord($buf) + (ord($buf)*256) + (ord($buf)*256*256) + (ord($buf)*256*256*256);
       $this->CountryFlag = ord ( $buf ) ;
       return $this->EndIp ;
   }

   function getCountry ( ) {

       switch ( $this->CountryFlag ) {
         case 1:
         case 2:
               $this->Country = $this->getFlagStr ( $this->EndIpOff+4);
               //echo sprintf('EndIpOffset=(%x)',$this->EndIpOff );
               $this->Local = ( 1 == $this->CountryFlag )? '' : $this->getFlagStr ( $this->EndIpOff+8);
               break ;
         default :
               $this->Country = $this->getFlagStr ($this->EndIpOff+4) ;
               $this->Local = $this->getFlagStr ( ftell ( $this->fp )) ;

       }
   }

   function getFlagStr ( $offset )
   {

       $flag = 0 ;
       while ( 1 ){
         @fseek ( $this->fp , $offset , SEEK_SET ) ;
         $flag = ord ( fgetc ( $this->fp ) ) ;
         if ( $flag == 1 || $flag == 2 ) {
               $buf = fread ($this->fp , 3 ) ;
               if ($flag == 2 ){
                   $this->CountryFlag = 2 ;
                   $this->EndIpOff = $offset - 4 ;
               }
               $offset = ord($buf) + (ord($buf)*256) + (ord($buf)* 256*256);
         }else{
               break ;
         }

       }
       if ( $offset < 12 )
         return '';
       @fseek($this->fp , $offset , SEEK_SET ) ;
       return $this->getStr();
   }
   function getStr ( )
   {
       $str = '' ;
       while ( 1 ) {
         $c = fgetc ( $this->fp ) ;
         if ( ord ( $c ) == 0 )
            break ;
         $str .= $c ;
       }
       return $str ;
   }

   function qqwry ($dotip) {

       $nRet;
       $ip = IpToInt ( $dotip );

       $this->fp= @fopen(QQWRY, "rb");
       if ($this->fp == NULL) {
             $szLocal= "OpenFileError";
         return 1;

         }
         @fseek ( $this->fp , 0 , SEEK_SET ) ;
       $buf = fread ( $this->fp , 8 ) ;
       $this->FirstStartIp = ord($buf) + (ord($buf)*256) + (ord($buf)*256*256) + (ord($buf)*256*256*256);
       $this->LastStartIp = ord($buf) + (ord($buf)*256) + (ord($buf)*256*256) + (ord($buf)*256*256*256);

       $RecordCount= floor( ( $this->LastStartIp - $this->FirstStartIp ) / 7);
       if ($RecordCount <= 1){
         $this->Country = "FileDataError";
         fclose ( $this->fp ) ;
         return 2 ;
       }

         $RangB= 0;
       $RangE= $RecordCount;
       // Match ...
       while ($RangB < $RangE-1)
       {
         $RecNo= floor(($RangB + $RangE) / 2);
         $this->getStartIp ( $RecNo ) ;

                   if ( $ip == $this->StartIp )
         {
               $RangB = $RecNo ;
               break ;
         }
         if ( $ip > $this->StartIp)
         $RangB= $RecNo;
         else
         $RangE= $RecNo;
       }
       $this->getStartIp ( $RangB ) ;
       $this->getEndIp ( ) ;

       if ( ( $this->StartIp <= $ip ) && ( $this->EndIp >= $ip ) ){
         $nRet = 0 ;
         $this->getCountry ( ) ;
         //这样不太好..............所以..........
         $this->Local = str_replace("(我们一定要解放台湾!!!)", "", $this->Local);

       }else {
         $nRet = 3 ;
         $this->Country = '未知' ;
         $this->Local = '' ;
       }
       fclose ( $this->fp ) ;
       return $nRet ;
   }
}

function ip2location ( $ip )
{
   $wry = new TQQwry ;
   $nRet = $wry->qqwry ( $ip );
return $wry->Country.$wry->Local ;
}
$testip="202.96.128.68";
echo ip2location($testip);
?>
页: [1]
查看完整版本: 奇怪的AMXX乘法????HELP