PDA

View Full Version : Where to get CTWB.simba



Boreas
12-30-2010, 03:25 AM
Brief Overview
CTWB is a set of functions that generate screenshots of the minimap to be uploaded to a community collection of bitmaps.

Users: how to get CTWB
Save this as CTWB.simba file in your includes folder. If would like to contribute, see next section.
{CTWB}

const
CTWBOn = false; //Make true to help out CTWB
CTWBPath = AppPath + 'CTWB\';

//lordsaturn
function CollectDots: TPointArray;
var
SearchColors: T2DIntegerArray;
TPA, TotalTPA: TPointArray;
i, j: Integer;
begin
SetLength(SearchColors, 3);
SearchColors[0] := [3553023, 789758, 2105598, 395004, 237, 206, 65536, 217, 188]; //red
SearchColors[1] := [16711422, 15527148, 13816530, 14869218, 12961221]; //white
SearchColors[2] := [1179390, 195836, 62965, 56797, 60909, 52428]; //yellow
for i := 0 to 2 do
begin
for j := 0 to High(SearchColors[i]) do
if FindColors(TPA, SearchColors[i][j], MMX1, MMY1, MMX2, MMY2) then
TotalTPA := CombineTPA(TotalTPA, TPA);
end;

Result := TotalTPA;
end;

//lordsaturn
function CollectSymbols: TPointArray;
var
SearchTPA, InsideTPA, OutlineTPA: TPointArray;
ATPA, SymbolATPA, PossiblesATPA, SearchATPA: T2DPointArray;
i, j, k, Hi, Hi2, Hi3, lowX, highX, x, y, L, L2, highCount, counter: Integer;
mid, aPt: TPoint;
SearchBox: TBox;
BadColors: TIntegerArray;
begin
//tpa of symbol outline, length = 40, midpoint = 7,7, bounds 14x14
SearchTPA := [Point(5, 0), Point(6, 0), Point(7, 0), Point(8, 0), Point(9, 0),
{5} Point(3, 1), Point(4, 1), Point(10, 1), Point(11, 1),
{9} Point(2, 2), Point(12, 2),
{11} Point(1, 3), Point(13, 3),
{13} Point(1, 4), Point(13, 4),
{15} Point(0, 5), Point(14, 5),
{17} Point(0, 6), Point(14, 6),
{19} Point(0, 7), Point(14, 7),
{21} Point(0, 8), Point(14, 8),
{23} Point(0, 9), Point(14, 9),
{25} Point(1, 10), Point(13, 10),
{27} Point(1, 11), Point(13, 11),
{29} Point(2, 12), Point(12, 12),
{31} Point(3, 13), Point(4, 13), Point(10, 13), Point(11, 13),
{35} Point(5, 14), Point(6, 14), Point(7, 14), Point(8, 14), Point(9, 14)];
BadColors := [789758, 217, 188, 206, 16711422, 14869218, 12961221, 13816530, 195836, 56797, 52428, 52428];
FindColors(InsideTPA, 12632256, MMX1, MMY1, MMX2, MMY2);
ATPA := TPAtoATPAEx(InsideTPA, 15, 15);
InsideTPA := []; //run faster
Hi := High(ATPA);
Hi3 := 39; //High(SearchTPA);
SetLength(SymbolATPA, Hi+1);
for i := 0 to Hi do
begin
//find top left, bottom right
SearchBox := GetTPABounds(ATPA[i]);
//get symbol outline
FindColors(OutlineTPA, 65536, SearchBox.x1-1, SearchBox.y1-1, SearchBox.x2+1, SearchBox.y2+1);

//build midpoint possibilities
Hi2 := High(OutlineTPA);
L2 := 0;
SetLength(PossiblesATPA, Hi2+1);
for j := 0 to Hi2 do
begin
if not (InIntArray(BadColors, GetColor(OutlineTPA[j].x, OutlineTPA[j].y-1))) then
begin
SetLength(PossiblesATPA[L2], Hi3+1);
for k := 0 to Hi3 do
begin
PossiblesATPA[L2][k].x := SearchTPA[k].x + OutlineTPA[j].x - 7;
PossiblesATPA[L2][k].y := SearchTPA[k].y + OutlineTPA[j].y - 7;
end;
Inc(L2);
end;
end;
OutlineTPA := []; //run faster
SetLength(PossiblesATPA, L2);

//find common midpoint
Hi2 := L2-1; //because it changed
highCount := 0;
for k := 0 to Hi3 do
begin
aPt := PossiblesATPA[0][k];
counter := 0;
for j := 1 to Hi2 do
if PointInTPA(aPt, PossiblesATPA[j]) then
Inc(counter);
if counter > highCount then
begin
mid := aPt;
highCount := counter;
end;
end;
PossiblesATPA := []; //run faster

//filler up
SetLength(SymbolATPA[i], 177);
if L = 0 then
SearchATPA := TPAtoATPAEx(SearchTPA, 15, 0); //go faster
L := 0;
Hi2 := 14; //High(SearchATPA);
for j := 0 to Hi2 do
begin
lowX := mid.x + SearchATPA[j][0].x - 7;
highX := mid.x + SearchATPA[j][High(SearchATPA[j])].x - 7;
y := mid.y + SearchATPA[j][0].y - 7;
for x := lowX to highX do
begin
SymbolATPA[i][L] := Point(x, y);
Inc(L);
end;
end;

end;
Result := MergeATPA(SymbolATPA);
end;

//lordsaturn
function StuffOnMM: TPointArray;
var
timer: Integer;
begin
Freeze;
timer := GetSystemTime;
Result := CombineTPA(CollectDots, CollectSymbols);
//Writeln('StuffOnMM took '+tostr(GetSystemTime-timer)+' msec.');
Unfreeze;
end;

procedure CTWBMakeClean(MyTile: TPoint);
var
CAB: TBox; //CurrentAreaBox
Chunks, Corners, Corners2, CopiedChunks, DotsTPA: TPointArray;
il, jl, t,i, i2, counter, MainBitmap, ChunkBitmap, FragmentBitmap, NewTarget, OldTarget: integer;
TmpString: String;
Skip: Boolean;
ChunksTiles, FragmentsTiles, FragmentsPixels, FragmentsPos: TBoxArray;
begin
t := getsystemtime;
//Get tile bounds of CurrentAreaBox
CAB := IntToBox(MyTile.x - 12, MyTile.y + 12, MyTile.x + 12, MyTile.y - 12);//Make sure this does not normalize

//CurrentAreaBox is spread over 1, 2, or 4 chunks, so these arrays are set to 4
//In these arrays, [0] corresponds to the chunk that the top left corner of CAB is in,
//[1] is top right, [2] is bottom left, [3] is bottom right. This defined in Corners
Corners := [Point(CAB.x1, CAB.y1), Point(CAB.x2, CAB.y1), Point(CAB.x1, CAB.y2), Point(CAB.x2, CAB.y2)];
SetArrayLength(Chunks, 4);
SetArrayLength(ChunksTiles, 4);
SetArrayLength(FragmentsTiles, 4);
SetArrayLength(FragmentsPixels, 4);
SetArrayLength(FragmentsPos, 4);

//Using these conventions when working with tiles and pixels
//Pixels have 0,0 in the top left
//Tiles have 0,0 in the bottom left
//Chunks have 0,0 in the bottom left (the are 100x100 pixels, but they deliberately start and end on tiles so that no tile
//is spread over multiple chunks (25x25 tiles), therefore, they follow the tile convention)
//X1,Y1 is always top left, X2,Y2 is always bottom right
//For pixels, Y1 is lower than Y2. For tiles and chunks, Y2 is lower than Y1

for i:= 0 to 3 do
begin
//Find the Chunk that the corresponding corner of CAB is in
Chunks[i] := Point(((Corners[i].x-2044) div 25),((Corners[i].y-861) div 25));
//Find the tile bounds of that chunk
ChunksTiles[i] := IntToBox(2044+Chunks[i].x*25, 885+Chunks[i].y*25, 2068+Chunks[i].x*25, 861+Chunks[i].y*25);//No normalize
//These are the opposite corners of Corners
Corners2 := [Point(ChunksTiles[i].x2, ChunksTiles[i].y2), Point(ChunksTiles[i].x1, ChunksTiles[i].y2), Point(ChunksTiles
[i].x2, ChunksTiles[i].y1), Point(ChunksTiles[i].x1, ChunksTiles[i].y1)]; //yes normalize
//Find the intersection of the corresponding Corner of CAB and the opposite corner of the Chunk
//that contains the Corner of CAB. Also make X1 lower than X2, and Y1 higher than Y2 (tiles start from the bottom left)
FragmentsTiles[i] := IntToBox(Min(Corners[i].x,Corners2[i].x), Max(Corners[i].y,Corners2[i].y), Max(Corners[i].x,Corners2
[i].x), Min(Corners[i].y, Corners2[i].y));
//Find the pixel bounds (on MainBitmap) of thoses tiles
FragmentsPixels[i] := IntToBox(14+(FragmentsTiles[i].x1-(MyTile.x-12))*4, 14+((MyTile.y+12)-FragmentsTiles[i].y1)*4, 112-
((MyTile.x+12)-FragmentsTiles[i].x2)*4, 112-(FragmentsTiles[i].y2-(MyTile.y-12))*4);
//Find the pixel box in Chunk that fragment will be copied to
FragmentsPos[i] := IntToBox((FragmentsTiles[i].x1-ChunksTiles[i].x1)*4, (ChunksTiles[i].y1-FragmentsTiles[i].y1)*4,
(FragmentsTiles[i].x1-ChunksTiles[i].x1)*4 + (FragmentsPixels[i].x2 - FragmentsPixels[i].x1),
(ChunksTiles[i].y1-FragmentsTiles[i].y1)*4 + (FragmentsPixels[i].y2 - FragmentsPixels[i].y1));
end;

DotsTPA :=StuffOnMM;

MainBitmap := BitmapFromClient(564, 21, 691, 148);
OldTarget := GetImageTarget;
SetTargetBitmap(MainBitmap);
NewTarget := GetImageTarget;

for i := 0 to High(DotsTPA) do
begin
il:=DotsTPA[i].x-564;
jl:=DotsTPA[i].y-21;
if (il > -1) and (il < 128) and (jl > -1) and (jl < 128) then
FastSetPixel(MainBitmap, il, jl, 0);
end;

for il:= mmcx-1 to mmcx+1 do
for jl:= mmcy-1 to mmcy +1 do
FastSetPixel(MainBitmap, il-564, jl-21, 0);

SetLength(CopiedChunks,1);
Counter := 0;
CopiedChunks[0] := Point(-1,-1);
for i:= 0 to 3 do
begin
Skip := false;
TmpString := 'CleanChunk'+ Padz(IntToStr(Chunks[i].x),2)+'-'+Padz(IntToStr(Chunks[i].y),2);
for i2 := 0 to High(CopiedChunks) do
begin
if ReadINI('CleanChunksDone', TmpString, CTWBPath + 'CTWBSVN\SVNCleanChunks.INI')='DONE' then
begin
Skip := true;
break;
end;
if ReadINI('CleanChunksDone', TmpString, CTWBPath + 'UserCleanChunks.INI')='DONE' then
begin
Skip := true;
break;
end;
if (Chunks[i].x = CopiedChunks[i2].x) and (Chunks[i].y = CopiedChunks[i2].y) then
begin
Skip := true;
break;
end;
end;
if not Skip then
begin
SetArrayLength(CopiedChunks, counter+1);
CopiedChunks[Counter] := Chunks[i];
Inc(Counter);
TmpString := CTWBPath + TmpString +'.bmp';
if FileExists(TmpString) then
ChunkBitmap := LoadBitmap(TmpString)
else
ChunkBitmap := CreateBitmap(100,100);
FragmentBitmap := BitmapFromClient(FragmentsPixels[i].x1, FragmentsPixels[i].y1,
FragmentsPixels[i].x2, FragmentsPixels[i].y2);
SetTransparentColor(FragmentBitmap, 0);
FastDrawTransparent(FragmentsPos[i].x1, FragmentsPos[i].y1, FragmentBitmap, ChunkBitmap);
FreeBitmap(FragmentBitmap);
SaveBitmap(ChunkBitmap, TmpString);

FreeBitmap(ChunkBitmap);
end;
end;

SetImageTarget(OldTarget);
FreeTarget(NewTarget);
FreeBitmap(MainBitmap);
end;




{************************************************* ******************************
function CTWBGetMyPos: TTile;
By: BenLand100
Description: Returns the global tile position of your player.
************************************************** *****************************}
function CTWBGetMyPos: TPoint;
var
me: Integer;
begin
me := SmartGetFieldObject(0, hook_static_MyPlayer);
Result.x := SmartGetFieldInt(0, hook_static_BaseX) + SmartGetFieldInt(me, hook_animable_PixelX) / 512;
Result.y := SmartGetFieldInt(0, hook_static_BaseY) + SmartGetFieldInt(me, hook_animable_PixelY) / 512;
SmartFreeObject(me);
if CTWBOn then
if R_MakeCompass('n') then
if not R_FlagExists then
CTWBMakeClean(Result);
end;

{************************************************* ******************************
function TileToMM(tile: TTile): TPoint;
By: BenLand100
Description: Converts the global tile position to a screen location on the
minimap, taking map rotation into account.
************************************************** *****************************}
function CTWBTileToMM(tile: TTile): TPoint;
var
angle, x, y: extended;
temp: TPoint;
begin
angle:= -GetMinimapAngleRad;
temp := CTWBGetMyPos();
x:= (tile.x - temp.x) * 4 - 2;
y:= (temp.y - tile.y) * 4 - 2;
result.x:= round(x*cos(angle) + y*sin(angle)) + 628;
result.y:= round(y*cos(angle) - x*sin(angle)) + 87;
end;

{************************************************* ******************************
function TileOnMM(Tile: TTile): boolean;
By: Drags111
Description: Checks if the Tile is on the MM.
************************************************** *****************************}
function CTWBTileOnMM(Tile: TTile): boolean;
var
P: TPoint;
begin
P := CTWBTileToMM(Tile);
Result := rs_OnMinimap(P.x, P.y);
end;

{************************************************* ******************************
Function WalkToTile(Tile: TPoint; Randomness, FlagD: Integer): Boolean;
By: Wizzup, TheGuyWhoGotOn, and Drags111
Description: Walks to the tile using minimap.
************************************************** *****************************}
function CTWBWalkToTile(TheTile: TTile; Randomness, FlagD: Integer): Boolean;
var
wTile: TPoint;
t: Integer;
begin
Result := False;
TheTile := RandomizeTile(TheTile, Randomness, Randomness);
wTile := CTWBTileToMM(TheTile);
if not rs_OnMiniMap(wTile.X, wTile.Y) then
Exit;
Mouse(wTile.x, wTile.y, 1, 1, true);
Wait(RandomRange(80, 100));
t := getsystemtime;
if (FlagD = 0)then
begin
R_Flag;
end else
R_FFlag(FlagD);
Result := (GetSystemTime - t) < 60000;
end;

{************************************************* ******************************
function WalkPath(Tiles: TTileArray): boolean;
By: Drags111
Description: Walks the tile path. Looks like an ugly function, but it works
Beautifully.
************************************************** *****************************}
function CTWBWalkPath(Tiles: TTileArray): boolean;
var
i, t, attempts: integer;
P: TPoint;
next: boolean;
label
ProcStart;
begin
Inc(attempts);
ProcStart:
i := -1;
Result := false;
if(DistanceFrom(Tiles[High(Tiles)]) < 6)then
begin
Result := true;
Exit;
end;

//Getting the starting index.
for i := High(Tiles) downto 0 do
if(CTWBTileOnMM(Tiles[i]))then
begin
i := i;
Break;
end;
if(i = -1)then
Exit;

//Walk remainder of the path.
for i := i to High(Tiles) do
begin
next := false;
if not(TileOnMM(Tiles[i]))then
begin
Writeln('Tile not on MM.');
break;
end;
P := CTWBTileToMM(Tiles[i]);
Mouse(P.x, P.y, 1, 1, true);
while(DistanceFromFlag <> 0)do
begin
if not WaitToMove(3000)then
begin
MarkTime(t);
while(TimeFromMark(t) < 7000)do
if(WaitToMove(1000))then break;
if(TimeFromMark(t) >= 7000)then
begin
Writeln('***Didn''t move for 10 seconds. Exiting***');
next := false;
break;
end;
end;
if(i < High(Tiles))then
begin
if(TileOnMM(Tiles[i+1]))then
begin
next := true;
break;
end;
end;
end;
if(i < High(Tiles))then
if(TileOnMM(Tiles[i+1]))then
next := true;
if not next then
break;
end;
Result := DistanceFrom(Tiles[High(Tiles)]) <= 5;
if not Result then
begin
if(attempts > 7)then
begin
Writeln('Failed more than ten attempts.');
Exit;
end;
While(GetSpeed > 0)do wait(100+Random(100));
goto ProcStart;
end;
While(GetSpeed > 0)do wait(100+Random(100));
end;

{************************************************* ******************************
Function WebWalk(T: TTile): Boolean;
By: JuKKa
Description: Walks blindly using WindPath!
************************************************** *****************************}
Function CTWBr_WebWalk(T: TTile): Boolean;
Var
I: Integer;
M, P: TPoint;
CTRLPoints: TPointArray;
Begin
P := TileToPoint(T);
Repeat
M := GetMyPos;
CtrlPoints := r_WindPath(M.x, M.y, P.X, P.Y, 5.0, 2.5, 0.0, 0.0, 4.5, 2.5);
For I:= High(CtrlPoints) DownTo 0 Do
if CTWBWalkToTile(Tile(CtrlPoints[i].x, CtrlPoints[i].y),0, 10) Then
Begin
Result := I = High(CtrlPoints);
Break;
End;
Until( Result );
End;



Users: how to enable CTWB
In CTWB.simba change 'CTWB = false;' to 'CTWB = true;'. You can also change CTWBPath if you would like. Now that CTWB is enabled, when you are running scripts that are CTWB Ready (they will have {$i CTWB.smba} at the top), bitmaps will be generated and saved to that path. Thanks for contributing!

Users: how to upload bitmaps
Once a week/month, or whenever you want, run this script.
<need to write a script that:
Downloads latest version of CommunityCompletedChunks.INI and StaticNPCTiles.INI,
SetPixel static NPC tiles yellow
Finds chunks with no remaining black, adds to UserCompletedChunks.INI, and uploads them to ???>

Scripters: how to make a script CTWB Ready
If your script uses reflection for walking, you can make it CTWB Ready (users still have to actually turn it on for it to do anything, see above). Add {$i CTWB.simba} after you include reflection. Wherever you call GetMyPos/WalkToTile/WalkPath, if making the compass north and an extra 250-1000ms won't hurt GetMyPos, replace them with CTWBGetMyPos/CTWBWalkToTile/CTWBWalkPath. On your script thread or in the instructions, link to this page so that users can get CTWB.simba. Thanks for contributing!

Extra information
CTWBGetMyPos takes screenshots of the minimap, and saves them to bitmaps. These bitmaps are named according to your current tile (hence the need for reflection). Dots and symbols are not included in these bitmaps, they are replaced with black. On the following runs, pixels that were black are updated (so the dots and symbols automagically disappear).

TomTuff
12-30-2010, 06:18 AM
question: what does CTWB stand for?

pyroryan
12-30-2010, 06:25 AM
Assuming a reflection hook is incorrect and you get some funny tiles for the screenshots, there is a way to revert right?

Boreas
12-30-2010, 02:53 PM
TomTuff: Color Tile Walking Base

pyroryan: nope, each bitmap is overwritten each time. So hopefully if the hooks are wrong they will be really wrong, so that it will be somewhere in the ocean or something.

Capricorn
12-30-2010, 03:27 PM
Is this to make a map so we can make easy paths? If so maybe 10 of us should just load it up, and walk around Runescape.

Boreas
12-30-2010, 03:42 PM
The PathMaker tool is for making paths. This will create a map that people can apply autocoloring type functions to, resulting in a color version of GetMyPos to walk those paths. So yea, we need lots of people to run reflection scripts walking around with this enabled.

Harry
12-30-2010, 04:12 PM
It could/should be ported to work with the MainScreen too, i.e. object finding?

How would the community backend work? Could probably use gd+perl for a simple database of the minimap images.

Pretty interesting.

Boreas
12-30-2010, 09:24 PM
It could/should be ported to work with the MainScreen too, i.e. object finding?.
You mean like knowing that a tree is at TileA and using a TileToMS that uses color_GetMyPos?



How would the community backend work? Could probably use gd+perl for a simple database of the minimap images.

Pretty interesting.

What do you mean? I was just thinking of making an SVN.

Frement
12-30-2010, 09:35 PM
I have PHP functions that can convert BitmapString from Simba to bitmap image on the server-side. They use GD ofcourse, I can find them and post here if you like?

Boreas
12-30-2010, 10:53 PM
Ah so instead of uploading bmp files, doing an HTTPPost thingy with the string?

Harry
12-30-2010, 11:29 PM
You mean like knowing that a tree is at TileA and using a TileToMS that uses color_GetMyPos?



What do you mean? I was just thinking of making an SVN.
1) Yeah sure.

2) Well I don't really know what its intended uses are for, but "to be uploaded to a community collection of bitmaps" - I assumed there would be some online backend that would collect automatically all the bitmaps?

Boreas
12-31-2010, 01:54 AM
I was just gonna make a script that puts the completed bmps into another folder and says 'please zip it up and upload, then post the link', but if you guys know a way to send from a script to a webserver automatically that would be awesome.

Zyt3x
12-31-2010, 01:56 AM
Just use some simple php functions

@Boreas: Check the other thread

BraK
01-05-2011, 07:46 PM
Stickied cause I love the Idea. New users this is probably a good start to color based world walker of the future.

~BraK

Boreas
01-06-2011, 02:50 AM
Thanks for that Brak.

Harry/Frement/Zyt3x: I don't know PHP/Perl/GD, but according to phpinfo() my basic shared hosting plan comes with "GD Version: bundled (2.0.34 compatible)" which doesn't support BMPs, but it comes with "ImageMagick version: ImageMagick 6.6.0-2" which does. Do you have a way to send BMPs from Simba to a webserver?

Frement
01-06-2011, 03:01 AM
Heres something I had in mind:

<?php

function gzuncompress_crc32($data) {
$f = tempnam('/tmp', 'gz_fix');
file_put_contents($f, "\x1f\x8b\x08\x00\x00\x00\x00\x00" . $data);
return file_get_contents('compress.zlib://' . $f);
}

function BMPStringToByteArray($string, $width, $height) {
if (substr($string, 0, 1) == "m") {
$data_array = str_split(gzuncompress_crc32(base64_decode(substr( $string, 1, strlen($string) - 1))));
$o = 1; $mode = R; $result = array();
$result["W"] = $width;
$result["H"] = $height;
foreach ($data_array as $bit) {
switch ($mode) {
case R: $r = $bit; $mode = G; break;
case G: $g = $bit; $mode = B; break;
case B: $b = $bit; $mode = R; $result[$o] = array(ord($r), ord($g), ord($b)); $o++; break;
}
}
return $result;
} else {
return false;
}
}

function ByteArrayToPNG($bytearray, $bmp_name) {
$width = $bytearray["W"];
$height = $bytearray["H"];
unset($bytearray["W"], $bytearray["H"]);
$img = imagecreatetruecolor($width, $height);
$sx = 0;
$sy = 0;
foreach ($bytearray as $bits) {
$color = imagecolorallocate($img, $bits[0], $bits[1], $bits[2]);
imagesetpixel($img, $sx, $sy, $color);
$sx++;
if ($sx == $width) {
$sy++;
$sx = 0;
}
}
imagepng($img, $bmp_name);
imagedestroy($img);
}

$bitmap["name"] = $_POST["bitmap_name"];
$bitmap["data"] = $_POST["bitmap_data"];
$bitmap["width"] = $_POST["bitmap_width"];
$bitmap["height"] = $_POST["bitmap_height"];

$bitmap_path = "bitmaps/";

$bytearray = BMPStringToByteArray($bitmap["data"], $bitmap["width"], $bitmap["height"]);

ByteArrayToPNG($bytearray, $bitmap_path.$bitmap["name"].".png");

?>

Boreas
01-06-2011, 03:49 AM
Ah cool. What would be the Simba side for that?

Also, would this convert it to a bmp without losing anything?


try
{
/*** the image file ***/
$image = $bitmap_path.$bitmap["name"].".png";

/*** a new imagick object ***/
$im = new Imagick();

/*** ping the image ***/
$im->pingImage($image);

/*** read the image into the object ***/
$im->readImage( $image );

/**** convert to png ***/
$im->setImageFormat( "bmp" );

/*** write image to disk ***/
$im->writeImage( '$bitmap_path.$bitmap["name"].".bmp"' );

echo 'Image Converted';
}
catch(Exception $e)
{
echo $e->getMessage();
}

Frement
01-06-2011, 03:53 AM
Something like this:
program new;

const ServerURL = 'http://www.frement.net/srl/ctwb/submit.php';

function SendBitmap(Bmp: Integer; Name: String): Boolean;
var Client, W, H: Integer;
Return: String;
begin
Result := False;
Client := InitializeHTTPClient(False);
ClearPostData(Client);
GetBitmapSize(Bmp, W, H);
AddPostVariable(Client, 'bitmap_name', Name);
AddPostVariable(Client, 'bitmap_data', CreateBitmapString(Bmp));
AddPostVariable(Client, 'bitmap_width', ToStr(W));
AddPostVariable(Client, 'bitmap_height', ToStr(H));
Return := PostHTTPPageEx(Client, ServerURL);
if (Pos('Success', Return) <> 0) then
Result := True;
end;

begin
if (SendBitmap(BitmapFromClient(0, 0, 50, 50), 'TestBitmap')) then
Writeln('Bitmap uploaded!');
end.

3Garrett3
01-10-2011, 07:46 PM
Has there been any development to the server side for this? If the Simba side works I'd be willing to make a script which simply walks around like crazy all over RS and then we could encourage a lot of people to use it, etc = win.

Boreas
01-10-2011, 08:13 PM
When I get a chance I will implement Frement's code into the uploader. Also needed for the uploader is a list of tiles of static NPCs.

However using CTWB with reflection scripts or an all over RS walker to collect bitmaps works now without the uploader script or server side, which would be win :)

3Garrett3
01-10-2011, 08:15 PM
When I get a chance I will implement Frement's code into the uploader. Also needed for the uploader is a list of tiles of static NPCs.

However using CTWB with reflection scripts or an all over RS walker to collect bitmaps works now without the uploader script or server side, which would be win :)

Yes, it would be more win if it auto updated/uploaded though

Boreas
01-10-2011, 08:41 PM
The thing is a bitmap isn't ready to be uploaded on the first pass. It takes several passes to be complete, so checking whether it is complete, and uploading it if it is, is done once a day/week or whenever the user wants via a separate uploader script. Also, the uploader script will color in yellow dots for static NPCs (which stay black normally and never trigger the IsComplete check), and I don't want to add too much real time processing to GetMyPos.