Advertisement
Guest User

LFS PRISM plugin ABGap 0.0.6

a guest
Feb 5th, 2016
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 7.53 KB | None | 0 0
  1. <?php
  2. class ABGap extends Plugins
  3. {
  4.     const URL = 'https://www.lfs.net/forum/thread/89031-ABGap-%28code-dump%2C-unsupported%29';
  5.     const NAME = 'ABGap';
  6.     const AUTHOR = 'notanillusion';
  7.     const VERSION = '0.0.6';
  8.     const DESCRIPTION = 'Gap delta to car ahead and behind';
  9.  
  10.     public function __construct() {    
  11.         $this->registerPacket('onLap', ISP_LAP);    // record times, display gaps
  12.         $this->registerPacket('onMci', ISP_MCI);    // update positions
  13.         $this->registerPacket('onNpl', ISP_NPL);    // add new plids
  14.         $this->registerPacket('onPll', ISP_PLL);    // remove unusued plids
  15.         $this->registerPacket('onRst', ISP_RST);    // update total splits and laps, fresh db table
  16.         $this->registerPacket('onSpx', ISP_SPX);    // record times, display gaps
  17.         $this->registerPacket('onSta', ISP_STA);    // update viewplid
  18.            
  19.         $this->consts = array(
  20.             'GAP_AHEAD' => -1,
  21.             'GAP_BEHIND' => 1,
  22.            
  23.             'SPLIT_LAP' => 255
  24.         );
  25.        
  26.         $this->db = $this->newDb();
  27.         if (!$this->db)
  28.             die('Failed to create database.'.PHP_EOL);
  29.  
  30.         $result = $this->createTable($this->db);
  31.         if (!$result)
  32.             die('Failed to create table.'.PHP_EOL);
  33.        
  34.         $this->playerData = array();    // plid => array(pos, lap), ...
  35.         $this->viewPlid = 0;
  36.         $this->laps = 0;
  37.         $this->splits = 0;
  38.     }
  39.    
  40.     public function __destruct() {
  41.         $this->db->close();
  42.     }
  43.    
  44.     /// *** PACKET FUNCTIONS START *** ///
  45.    
  46.     public function onLap(IS_LAP $lap) {
  47.         if (!count($this->playerData))      // ignore hotlap mode
  48.             return;
  49.        
  50.         $pos = $this->playerData[$lap->PLID]['pos'];
  51.            
  52.         $q = "INSERT INTO timing (plid, lap, split, pos, time)
  53.             VALUES ($lap->PLID, $lap->LapsDone, ".$this->consts['SPLIT_LAP'].", $pos, $lap->ETime)";
  54.            
  55.         $result = $this->db->exec($q);
  56.        
  57.         // Don't check for gap ahead if we're 1st.
  58.         if ($lap->PLID === $this->viewPlid && $this->playerData[$this->viewPlid]['pos'] > 1) {
  59.             $plidAhead = $this->getPlidAhead($pos, $lap->LapsDone, $this->consts['SPLIT_LAP']);
  60.            
  61.             // Sometimes when cars are really close to one another across a split, the SPX for the car behind in positions
  62.             // can arrive first. Don't display gap when that happens.
  63.             if ($plidAhead === null) {
  64.                 return;
  65.             }
  66.             $this->sendGap($plidAhead, $this->consts['GAP_AHEAD'], $lap->LapsDone, $this->consts['SPLIT_LAP']);
  67.         }
  68.        
  69.         // Don't check for gap behind if we're last.
  70.         if (!$this->isLastPlaceByPlid($this->viewPlid)) {
  71.             if ($this->getPlidAhead($pos, $lap->LapsDone, $this->consts['SPLIT_LAP']) == $this->viewPlid)
  72.                 $this->sendGap($lap->PLID, $this->consts['GAP_BEHIND'], $lap->LapsDone, $this->consts['SPLIT_LAP']);
  73.         }
  74.     }
  75.  
  76.     public function onMci(IS_MCI $mci) {
  77.         foreach ($mci->Info as $compcar) {
  78.             if (!$compcar->Position)
  79.                 continue;
  80.             $this->playerData[$compcar->PLID]['pos'] = $compcar->Position;
  81.             $this->playerData[$compcar->PLID]['lap'] = $compcar->Lap;
  82.         }
  83.     }
  84.    
  85.     public function onNpl(IS_NPL $npl) {
  86.         $this->playerData[$npl->PLID]['pos'] = $npl->NumP;
  87.         $this->playerData[$npl->PLID]['lap'] = 1;
  88.     }
  89.    
  90.     public function onPll(IS_PLL $pll) {
  91.         unset($this->playerData[$pll->PLID]);
  92.     }
  93.    
  94.     public function onRst(IS_RST $rst) {
  95.         $this->laps = $rst->RaceLaps;
  96.         $this->splits = $this->getNumSplitsRst($rst);
  97.        
  98.         $this->playerData = array();
  99.        
  100.         $result = $this->createTable($this->db);
  101.         if (!$result) {
  102.             echo('Failed to create table.'.PHP_EOL);
  103.             return;
  104.         }
  105. }
  106.    
  107.     public function onSpx(IS_SPX $spx) {
  108.         if (!count($this->playerData))
  109.             return;
  110.        
  111.         $pos = $this->playerData[$spx->PLID]['pos'];
  112.         $lap = $this->playerData[$spx->PLID]['lap'];
  113.        
  114.         if (!$lap) $lap++;
  115.        
  116.         $q = "INSERT INTO timing (plid, lap, split, pos, time)
  117.             VALUES ($spx->PLID, $lap, $spx->Split, {$this->playerData[$spx->PLID]['pos']}, $spx->ETime)";
  118.            
  119.         $result = $this->db->exec($q);
  120.        
  121.         if ($spx->PLID === $this->viewPlid && $this->playerData[$this->viewPlid]['pos'] > 1) {
  122.             $plidAhead = $this->getPlidAhead($pos, $lap, $spx->Split);
  123.            
  124.             if ($plidAhead === null) {
  125.                 return;
  126.             }
  127.             $this->sendGap($plidAhead, $this->consts['GAP_AHEAD'], $lap, $spx->Split);
  128.         }
  129.        
  130.         if (!$this->isLastPlaceByPlid($this->viewPlid)) {
  131.             if ($this->getPlidAhead($pos, $lap, $spx->Split) == $this->viewPlid) {
  132.                 $this->sendGap($spx->PLID, $this->consts['GAP_BEHIND'], $lap, $spx->Split);
  133.             }
  134.         }
  135.     }
  136.    
  137.     public function onSta(IS_STA $sta) {
  138.         $this->viewPlid = $sta->ViewPLID;
  139.     }
  140.    
  141.     /// *** PACKET FUNCTIONS END *** ///
  142.    
  143.     function createTable($db) {
  144.         $q = 'DROP TABLE timing';
  145.         @$this->db->exec($q);
  146.        
  147.         $q = 'CREATE TABLE timing(
  148.             id INTEGER PRIMARY KEY ASC,
  149.             plid INTEGER,
  150.             lap INTEGER,
  151.             split INTEGER,
  152.             pos INTEGER,
  153.             time INTEGER
  154.         )';
  155.        
  156.         $result = $this->db->exec($q);
  157.  
  158.         return $result;
  159.     }
  160.    
  161.     function getNumSplitsRst($rst) {
  162.         $splits = 0;
  163.        
  164.         for ($i = 3; $i > 0; $i--) {
  165.             if ($rst->{"Split$i"} && $rst->{"Split$i"} != 65535) {
  166.                 $splits = $i;
  167.                 break;
  168.             }
  169.         }
  170.         return $splits;
  171.     }
  172.    
  173.     function getPlidAhead($pos, $lap, $split) {
  174.         $pos--;
  175.  
  176.         $q = "SELECT plid FROM timing WHERE pos=$pos AND lap=$lap AND split=$split;";
  177.         $result = $this->db->query($q);
  178.        
  179.         if ($result === false)
  180.             return;
  181.         $row = $result->fetchArray();
  182.        
  183.         return $row['plid'];
  184.     }
  185.    
  186.     function getTime($plid, $lap, $split) {
  187.         $q = "SELECT * FROM timing WHERE plid=$plid AND lap=$lap AND split=$split;";
  188.         $result = $this->db->query($q);
  189.        
  190.         $time = 0;
  191.  
  192.         while($row = $result->fetchArray()) {
  193.             if (array_key_exists('time', $row))
  194.                 $time = $row['time'];
  195.         }
  196.        
  197.         return $time;
  198.     }
  199.    
  200.     function isLastPlaceByPlid($plid) {
  201.         if ($this->playerData[$plid]['pos'] >= count($this->playerData)) {
  202.             return true;
  203.         }
  204.        
  205.         return false;
  206.     }
  207.    
  208.     function ms2str ($ms, $ahead) {
  209.         $retval = '';
  210.        
  211.         $hour = abs($ms / (1000 * 60 * 60));
  212.         if ($hour >= 1) {
  213.             $retval .= strval(intval($hour)) . ':';
  214.         }
  215.        
  216.         $min = ($hour - intval($hour)) * 60;
  217.         if ($hour >= 1 && $min < 1) {
  218.             $retval .= '00:';
  219.         }
  220.         else if ($min >= 10) {
  221.             $retval .= strval(intval($min)) . ':';
  222.         }
  223.         else if ($min > 1 && $min < 10) {
  224.             $retval .= '0' . strval(intval($min)) . ':';
  225.         }
  226.        
  227.         $sec = ($min - intval($min)) * 60;
  228.         $retval .= number_format($sec, 3);
  229.        
  230.         if ($ms >= 0 && $ahead < 0) {
  231.             $retval = "^1+$retval";
  232.         }
  233.        
  234.         if ($ms < 0 && $ahead < 0) {
  235.             $retval = "^2-$retval";
  236.         }
  237.        
  238.         if ($ms >= 0 && $ahead > 0) {
  239.             $retval = "^1-$retval";
  240.         }
  241.        
  242.         if ($ms < 0 && $ahead > 0) {
  243.             $retval = "^2+$retval";
  244.         }
  245.        
  246.         return $retval;
  247.     }
  248.    
  249.     function newDb() {
  250.         $db = new SQLite3(':memory:');
  251.         return $db;
  252.     }
  253.    
  254.     function getGap($a, $b, $lap, $split) {
  255.         $plidACurTime = $this->getTime($a, $lap, $split);
  256.         $plidBCurTime = $this->getTime($b, $lap, $split);
  257.         $gap = $plidACurTime - $plidBCurTime;
  258.        
  259.         return $gap;
  260.     }
  261.    
  262.     function sendGap($plid, $mode, $lap, $split) {
  263.         if ($split === false)
  264.             return;
  265.        
  266.         if ($this->splits === 0) {
  267.             $split = 255;
  268.         }
  269.        
  270.         $curGap = $this->getGap($this->viewPlid, $plid, $lap, $split);
  271.        
  272.         switch ($split) {
  273.             case 255:
  274.                 $split = $this->splits;
  275.             break;
  276.            
  277.             case 1:
  278.                 $split = 255;
  279.                 $lap--;
  280.             break;
  281.            
  282.             default:
  283.                 if ($this->splits === 0) {
  284.                     $lap--;
  285.                 } else {
  286.                     $split--;
  287.                 }
  288.             break;
  289.         }
  290.        
  291.         $prevGap = $this->getGap($this->viewPlid, $plid, $lap, $split);
  292.        
  293.         $gapDelta = $curGap - $prevGap;
  294.  
  295.         if ($mode == $this->consts['GAP_BEHIND']) {
  296.             $msg = '^3Gap delta to car behind: ';
  297.         } else {
  298.             $msg = '^3Gap delta to car ahead: ';
  299.         }
  300.        
  301.         $timemsg = $this->ms2str($gapDelta, $mode);
  302.         $msg .= $timemsg;
  303.        
  304.         IS_MSL()->Msg($msg)->Send();
  305.     }
  306. }
  307. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement