2008年04月23日
グループを作ってばかりいると金がかかる
グループ登録で遊んでいる。
>public void Invite(LLUUID group, List roles, LLUUID personkey)
なんで、
CurrentGroupsCallback、GroupProfileCallback、GroupRolesCallbackしている。
#参考:ロール:[00000000000000000000000000000000, Everyone]
固定値を渡すならいいが、組み合わせて合わせ技で一本にしようとすると、
ぞろぞろ書かなければならない。
AgentManagerには、
>public delegate void AgentDataCallback(string firstName, string lastName, LLUUID activeGroupID,
> string groupTitle, GroupPowers groupPowers, string groupName);
なんてのもある。
ScriptSensorReplyCallback なんてのも見つけたが、また今度。
グループをぽこぽこ作ったらあっという間に残金が減った。
1グループ100L$かかる。
キャンプBOTを書いたほうがいいのか?
素直にSLEEK使えという気もする。
>public void Invite(LLUUID group, List
なんで、
CurrentGroupsCallback、GroupProfileCallback、GroupRolesCallbackしている。
#参考:ロール:[00000000000000000000000000000000, Everyone]
固定値を渡すならいいが、組み合わせて合わせ技で一本にしようとすると、
ぞろぞろ書かなければならない。
AgentManagerには、
>public delegate void AgentDataCallback(string firstName, string lastName, LLUUID activeGroupID,
> string groupTitle, GroupPowers groupPowers, string groupName);
なんてのもある。
ScriptSensorReplyCallback なんてのも見つけたが、また今度。
グループをぽこぽこ作ったらあっという間に残金が減った。
1グループ100L$かかる。
キャンプBOTを書いたほうがいいのか?
素直にSLEEK使えという気もする。
2008年04月23日
TestClientにvoice 関連のコマンドが追加された
http://bug.opensecondlife.org/view.php?id=220
http://cia.vc/stats/author/jradford/.message/895d
>Author: jradford
>Project: libsl
>Revision: 1753
>
>Adds two TestClient commands: ParcelVoiceInfo VoiceAcountCommand
> to display parcel's voice settings and to display voice account information
> Courtesy of DrScofield Mantis#220
これは試してみる価値がある!
http://cia.vc/stats/author/jradford/.message/895d
>Author: jradford
>Project: libsl
>Revision: 1753
>
>Adds two TestClient commands: ParcelVoiceInfo VoiceAcountCommand
> to display parcel's voice settings and to display voice account information
> Courtesy of DrScofield Mantis#220
これは試してみる価値がある!
2008年04月08日
CookComputing.XmlRpcV2 のエラーの時
libsecondlife.dllがCLRとして使えるようになっているので、
FePyから使おうと「import clr」「clr.AddReferenceToFile("libsecondlife.dll")」
とやったときに、「print sys.path」で出る位置にはlibsecondlife.dllが入っているのに、
以下のエラーが出る場合は、http://www.xml-rpc.net/ から「xml-rpc.net.2.3.0.zip」
http://xmlrpcnet.googlecode.com/files/xml-rpc.net.2.3.0.zip なんてやつを
DLして展開して、
展開してできたbin\CookComputing.XmlRpcV2.dll を、ライブラリに追加する。
sys.pathで出てくるパスのディレクトリの直下に入れることに注意。
配置例: IPCE-r7\ipy\Lib\CookComputing.XmlRpcV2.dll
新しいPCをゲットした人は注意です^^;
---
C:\>ipy
IronPython 1.1 (1.1) on .NET 2.0.50727.1433
Copyright (c) Microsoft Corporation. All rights reserved.
>>> import clr
>>>
>>> clr.AddReferenceToFile("xxx")
Traceback (most recent call last):
File , line 0, in
File , line 0, in AddReferenceToFile##50
IOError: Could not add reference to assembly xxx
>>>
>>> clr.AddReferenceToFile("libsecondlife.dll")
Traceback (most recent call last):
File , line 0, in
File , line 0, in AddReferenceToFile##50
IOError: ファイルまたはアセンブリ 'CookComputing.XmlRpcV2,
Version=0.0.0.0, Cult
ure=neutral, PublicKeyToken=null'、またはその依存関係の 1 つが読み込めま
せんでし
た。指定されたファイルが見つかりません。
>>>
>>>
---
.NET Framework 2.0以上がインストールされていない場合は適当にgoogleで検索汁。
2008年04月04日
灰色のハーレム
ハーレムを作りたくて、30人ほど呼んでみた。
libsecondlifeでLoginしただけで放置しているせいか、0.3.0を使っているせいか、全員全身灰色だ。
で、しばらく眺めていたら何人かは全身肌色に。
服を買って欲しいとか言ってきた事は無かったが、少しは買ってやろうかと思う。
制服やスーツはいいが、野球のユニフォームを着せると何かが違う気がする。
うちのマシンでは30人を越えたあたりから厳しくなる。
ビューアを最小化してもipy.exeがCPU=70%てのは高いほうだと思う。

マップで緑の柱が立つので発見され「兵隊みたい」と言われてしまった。
お騒がせしてすいません。人が集まる他人の土地でやるべきじゃなかったですね。
libsecondlifeでLoginしただけで放置しているせいか、0.3.0を使っているせいか、全員全身灰色だ。
で、しばらく眺めていたら何人かは全身肌色に。
服を買って欲しいとか言ってきた事は無かったが、少しは買ってやろうかと思う。
制服やスーツはいいが、野球のユニフォームを着せると何かが違う気がする。
うちのマシンでは30人を越えたあたりから厳しくなる。
ビューアを最小化してもipy.exeがCPU=70%てのは高いほうだと思う。

マップで緑の柱が立つので発見され「兵隊みたい」と言われてしまった。
お騒がせしてすいません。人が集まる他人の土地でやるべきじゃなかったですね。
2007年12月30日
SLアイテム検索ページ仮実装しました
これまでに投稿した記事にあるlibsecondlifeを使った情報収集を使って、
Secondlife内のアイテムの一部が検索できるページを仮実装しました。
http://www.march.awk.jp/itemInfo/itemCondition.php
Secondlife内で販売されているオブジェクト(以下、商品)に
関する情報を自動的に収集して本システム内のデータベースに格納し、
WEB画面から検索し販売場所にテレポートできるようにするシステムです。
公式ビューアでの検索に比べ、商品情報だけが検索できますが、
私が立ち寄る店限定なので、アイテム数は超少ないです。

あきらかなバグや情けない問題も含んでいますが、
こんな事もできるというサンプルとして公開します。
各商品のパッケージに使われている画像をサムネイルとして使わせてもらっていますが、
それぞれの権利は各持ち主にありますので、転載などはご遠慮ください。
また、何か問題あるようでしたら削除しますので、リプライやIMなどで
連絡をお願いしますm_()_m
Secondlife内のアイテムの一部が検索できるページを仮実装しました。
http://www.march.awk.jp/itemInfo/itemCondition.php
Secondlife内で販売されているオブジェクト(以下、商品)に
関する情報を自動的に収集して本システム内のデータベースに格納し、
WEB画面から検索し販売場所にテレポートできるようにするシステムです。
公式ビューアでの検索に比べ、商品情報だけが検索できますが、
私が立ち寄る店限定なので、アイテム数は超少ないです。

あきらかなバグや情けない問題も含んでいますが、
こんな事もできるというサンプルとして公開します。
各商品のパッケージに使われている画像をサムネイルとして使わせてもらっていますが、
それぞれの権利は各持ち主にありますので、転載などはご遠慮ください。
また、何か問題あるようでしたら削除しますので、リプライやIMなどで
連絡をお願いしますm_()_m
タグ :libsl
2007年12月13日
libsecondlifeサンプル - 画像の取得
テクスチャのUUIDを指定して、テクスチャ画像をJPEG 2000形式でAsset serverから
取得しファイル等に保存することができます。
処理の流れは以下のとおりです。
1.あらかじめテクスチャデータ処理用のハンドラを登録しておく
2.client.Assets.RequestImage関数を使ってリクエストを出す
3.ハンドラの関数でファイルや変数に保存する
以下はサンプルコードです。
こんな画像が取得できます(私が配布しているメッセージカードの販売箱のテクスチャです)

・他にも、RequestImages関数としてリストで渡して複数テクスチャを一度に受け取る関数もあります。
AssetManager.csを参照してください。
注意!
画像に関する権利は画像の作者や画像の管理者にあります。
簡単にコピーが取れるからといって、他人の画像を勝手に自分の商品として売ったりしないよう注意しましょう。
取得しファイル等に保存することができます。
処理の流れは以下のとおりです。
1.あらかじめテクスチャデータ処理用のハンドラを登録しておく
2.client.Assets.RequestImage関数を使ってリクエストを出す
3.ハンドラの関数でファイルや変数に保存する
以下はサンプルコードです。
#libsecondlifeのロード
import clr
clr.AddReferenceToFile("libsecondlife.dll")
import libsecondlife
import time
import os
#ログイン情報の設定
firstName = 'abcd' #苗字
lastName = 'efgh' #名前
passWord = 'ijkl' #パスワード
#イベント待ち合わせ用クラスの定義
class EventTracker:
def __init__(self):
self.data=False
def Clear(self):
self.data=False
def Set(self):
self.data=True
def Wait(self):
while not self.data:
time.sleep(0.1)
def WaitTimeout(self, s):
t = time.time()
while not self.data:
time.sleep(0.1)
if(t < time.time() - s):
print 'event timeout',
break
else:
#print 'wait,..', t, s, time.time(),
pass
#テクスチャデータ処理用のハンドラの定義
def ImageReceivedHandler(image, asset):
print 'image.ID=', image.ID, 'image.Success=', image.Success
if(image.Success):
#jp2ファイルとして出力
fp_out = open((image.ID).ToString() + '.jp2', 'wb')
for i in range(len(image.AssetData)):
fp_out.write( chr(image.AssetData[i]) )
fp_out.close()
print 'wrote ', len(image.AssetData), 'bytes'
event.Set()
#初期設定
event = EventTracker()
client = libsecondlife.SecondLife()
client.Assets.OnImageReceived += client.Assets.ImageReceivedCallback(ImageReceivedHandler)
#接続
client.Network.Login(firstName, lastName, passWord, '', '')
time.sleep(10)
#実際の処理(1つずつテクスチャを取得)
imageUuidList = [
'13c20952-8cce-27a8-8e18-05c19bc59147', #clownfish(244 Free Textures -04/04-(YadNi s Junkyard))
'dc22d88c-6e8d-0203-e637-fc1b9f4ebe0b', #BirthdayCard-PACKAGE
'f05dd50c-92f1-3575-f00c-527bcb9b46c4' #unicode-0x30-sazanami-gothic-transparent
]
for i in range(len(imageUuidList)):
event.Clear()
imageType = libsecondlife.ImageType.Baked
resultUuid = libsecondlife.LLUUID(imageUuidList[i])
requestImageRet = client.Assets.RequestImage(resultUuid, imageType, 100000.0, 0)
event.WaitTimeout(30)
time.sleep(1)
#切断
client.Network.Logout()
こんな画像が取得できます(私が配布しているメッセージカードの販売箱のテクスチャです)

・他にも、RequestImages関数としてリストで渡して複数テクスチャを一度に受け取る関数もあります。
AssetManager.csを参照してください。
注意!
画像に関する権利は画像の作者や画像の管理者にあります。
簡単にコピーが取れるからといって、他人の画像を勝手に自分の商品として売ったりしないよう注意しましょう。
2007年12月12日
libsecondlifeサンプル - オブジェクト情報取得
オブジェクトがRezされたり更新されたり削除されたりした場合に、
そのオブジェクトの情報を取得することが出来ます。
オブジェクトの情報には、以下の情報が含まれています。
右クリックしてパイメニューの「Edit」で得られる情報はほぼ取得できそうです。
・基本的な情報(LLObjectクラス)、
UUIDや置かれている位置やテクスチャUUIDなど
・プロパティ情報(ObjectPropertiesFamily構造体、ObjectProperties構造体)、
名前や販売種別や販売価格など
・プリム情報(Primitiveクラス)、
テーパ角度、物理属性か否かなど
オブジェクトの情報の取得は以下の流れです。
(他にもっとスマートなやり方がありそうですが…)
前にこのBLOGでも少し書いた、0L$以上で販売しているオブジェクトの情報の取得は
このやり方です。
1.取得したいオブジェクトのある場所にログイン/テレポートする
2.OnNewPrimイベントでオブジェクトのUUIDを得る
3.RequestObjectPropertiesFamilyで上記のUUIDのオブジェクトのプロパティを要求する
4.OnObjectPropertiesFamilyイベントでプロパティを得る
・この方法では、近くにあるはずのオブジェクトの情報が取得できていない
場合があります。
公式クライアントで見たときのように、アバターの体の向きを変えたり
歩き回ったりすればいいのかも知れませんが、未調査です。
・OnNewPrimは名前のとおり新しいプリムを発見したときに発生するイベントなので、
既にログイン/テレポートしてから時間がたった後で
自分の周囲にあるオブジェクトのUUIDを得ようとする場合には使えません。
・OnNewPrimイベントは1オブジェクトごとに発生するので、
数分で数千回~数万回程度呼ばれる場合が多いため、いったん配列などに入れて
イベントハンドラ外で非同期に処理したほうがいいかもしれません。
・プロパティ情報を要求してもOnObjectPropertiesFamilyイベントが発生せず
情報が得られない場合があります。
・スレッドプールが不足した旨のエラーで落ちる場合があります。
0.3.1リリースノートにあるようにlibsecondlife側の問題です。
http://www.libsecondlife.org/wiki/libsecondlife:Release_Notes/0.3.1
以下はサンプルコードです。
#libsecondlifeのロード
import clr
clr.AddReferenceToFile("libsecondlife.dll")
import libsecondlife
import time
#ログイン情報の設定
firstName = 'abcd' #苗字
lastName = 'efgh' #名前
passWord = 'ijkl' #パスワード
#各オブジェクトの情報
primSummary = {} #オブジェクトの基本的な情報
sims = {} #オブジェクトの置いてあるSIM
primProperties = {} #オブジェクトのプロパティ情報
#イベント待ち合わせ用クラスの定義
class EventTracker:
def __init__(self):
self.data=False
def Clear(self):
self.data=False
def Set(self):
self.data=True
def Wait(self):
while not self.data:
time.sleep(0.1)
def WaitTimeout(self, s):
t = time.time()
while not self.data:
time.sleep(0.1)
if(t < time.time() - s):
print 'event timeout',
break
else:
#print 'wait,..', t, s, time.time(),
pass
#新規オブジェクト検出イベント処理用のハンドラの定義
def NewPrimHandler(sim, prim, regionHandle, timeDilation):
#オブジェクトの情報を辞書に格納
global sims, primSummary
if(primSummary.has_key(prim.ID)):
return
sims[prim.ID] = sim
primSummary[prim.ID] = prim
#プリムの基本情報の取得
#print client.Objects.RequestObject(sim, prim.LocalID)
#プリムのプロパティ情報の取得
client.Objects.RequestObjectPropertiesFamily(client.Network.CurrentSim, prim.ID)
#オブジェクト情報取得イベント処理用のハンドラの定義
def ObjectPropertiesFamilyHandler(sim, properties):
global primSummary, primProperties #, gItemPointer
if(primProperties.has_key(properties.ObjectID)):
return
primProperties[properties.ObjectID] = properties
#初期設定
event = EventTracker()
client = libsecondlife.SecondLife()
client.Objects.OnNewPrim += libsecondlife.ObjectManager.NewPrimCallback(NewPrimHandler)
client.Objects.OnObjectPropertiesFamily += libsecondlife.ObjectManager.ObjectPropertiesFamilyCallback(ObjectPropertiesFamilyHandler)
#接続
client.Network.Login(firstName, lastName, passWord, '', '')
time.sleep(10)
#実際の処理(10秒まって、周囲のオブジェクトの情報を出力)
client.Objects.OnNewPrim -= libsecondlife.ObjectManager.NewPrimCallback(NewPrimHandler)
time.sleep(10)
for i in primSummary.keys():
#オブジェクトの基本的な情報の出力
print 'sim =', sims[i]
print 'prim.Position =', primSummary[i].Position
print 'prim =', primSummary[i]
#オブジェクトのプロパティ情報の出力
if primProperties.has_key(i):
p = primProperties[i]
print 'Name =', p.Name
print 'Description =', p.Description
print 'SaleType =', p.SaleType
print 'SalePrice =', p.SalePrice #@see ObjectManager.cs #Not / Original / Copy / Contents
print 'Category =', p.Category
print 'GroupID =', p.GroupID
print 'LastOwnerID =', p.LastOwnerID
print 'ObjectID =', p.ObjectID
print 'OwnerID =', p.OwnerID
print 'OwnershipCost =', p.OwnershipCost #0.3.0
print 'Permissions =', p.Permissions #0.3.0
else:
print 'no propertiesFamilly'
print '---'
#切断
client.Network.Logout()
以下のページも参考になります。
http://www.cs.unc.edu/~rgayle/Comp790-058/lectures/Comp790-BotsAndPlanning.ppt
2007年12月11日
libsecondlifeサンプル - チャットとIM送受信
チャンネルを指定したチャットや、相手のUUIDを指定したIMの送信ができます。
libsecondlifeのDeveloper Portal にある以下のページを参照してください。
http://www.libsecondlife.org/wiki/Say_something_inworld_%28chat%29
http://www.libsecondlife.org/wiki/Respond_to_inworld_chat
http://www.libsecondlife.org/wiki/Send_an_instant_message
http://www.libsecondlife.org/wiki/Respond_to_instant_messages
使い方によってはスパムになるので注意しましょう。
以下はサンプルコードです。
自分でチャットに発言した内容を自分で拾っています。
タイピングの開始/終了は出していません。
聞こえる範囲には、Whisper, Normal, Shoutの3つが選べます。
ChatType.Say は古い仕様で削除予定なので使用しないようにとの説明が上記のページにあります。
また、自分にIMを送信し受信しています。
AgentManager.cs には、グループIMを送信するための関数もあります。
AgentManager.cs を参照ください。
例:client.Self.InstantMessageGroup(groupUuid, msg)
チャットの内容から特定の単語を拾って、挨拶と簡単な受け答えができ、
詳しい話が聞きたいという人には、担当者を呼ぶのでお待ちくださいと言うような、
コールセンター風の使い方をしてもいいかもしれません。
(外見は普通のアバターですし)
libsecondlifeのDeveloper Portal にある以下のページを参照してください。
http://www.libsecondlife.org/wiki/Say_something_inworld_%28chat%29
http://www.libsecondlife.org/wiki/Respond_to_inworld_chat
http://www.libsecondlife.org/wiki/Send_an_instant_message
http://www.libsecondlife.org/wiki/Respond_to_instant_messages
使い方によってはスパムになるので注意しましょう。
以下はサンプルコードです。
自分でチャットに発言した内容を自分で拾っています。
タイピングの開始/終了は出していません。
聞こえる範囲には、Whisper, Normal, Shoutの3つが選べます。
ChatType.Say は古い仕様で削除予定なので使用しないようにとの説明が上記のページにあります。
また、自分にIMを送信し受信しています。
#libsecondlifeのロード
import clr
clr.AddReferenceToFile("libsecondlife.dll")
import libsecondlife
import time
#ログイン情報の設定
firstName = 'abcd' #苗字
lastName = 'efgh' #名前
passWord = 'ijkl' #パスワード
#イベント待ち合わせ用クラスの定義
class EventTracker:
def __init__(self):
self.data=False
def Clear(self):
self.data=False
def Set(self):
self.data=True
def Wait(self):
while not self.data:
time.sleep(0.1)
#チャットイベント処理用ハンドラの定義
def chatHandler(message, hearRange, chatType, chatSourceType, agentName, uuid1, uuid2, locationVector):
print 'message =', message
print 'hearRange =', hearRange
print 'chatType =', chatType #StartTyping, Normal, StopTyping
print 'chatsourceType =', chatSourceType
print 'agentName =', agentName
print 'uuid1 =', uuid1 #SourceID?
print 'uuid2 =', uuid2 #OwnerID?
print 'locationVector =', locationVector
#IM受信イベント処理用のハンドラの定義
def instantMessageHandler(im, sim):
print 'sim=', sim.ToString()
attrList = [
'ToAgentID',
'FromAgentID',
'FromAgentName',
'ParentEstateID',
'RegionID',
'Position',
'Dialog',
'GroupIM',
'IMSessionID',
'Timestamp',
'Message',
'Offline',
'BinaryBucket'
]
for i in attrList:
print i, '=', eval('im.%s' % (i) )
#初期設定
event = EventTracker()
client = libsecondlife.SecondLife()
client.Self.OnChat += libsecondlife.AgentManager.ChatCallback(chatHandler)
client.Self.OnInstantMessage += libsecondlife.AgentManager.InstantMessageCallback(instantMessageHandler)
#接続
client.Network.Login(firstName, lastName, passWord, '', '')
time.sleep(10)
#実際の処理
#現在時刻をチャットで発言する
msg = 'now ' + time.strftime('%Y-%m-%d %H:%M:%S')
chatType = libsecondlife.ChatType.Normal #ChatType.Say is obsolete version and will likely be removed in the near future.
client.Self.Chat(msg, 0, chatType)
time.sleep(10)
#自分自身にIMを送信する
targetUuid = client.Self.AgentID
msg = 'now ' + time.strftime('%Y-%m-%d %H:%M:%S')
client.Self.InstantMessage(targetUuid, msg)
time.sleep(10)
#切断
client.Network.Logout()
AgentManager.cs には、グループIMを送信するための関数もあります。
AgentManager.cs を参照ください。
例:client.Self.InstantMessageGroup(groupUuid, msg)
チャットの内容から特定の単語を拾って、挨拶と簡単な受け答えができ、
詳しい話が聞きたいという人には、担当者を呼ぶのでお待ちくださいと言うような、
コールセンター風の使い方をしてもいいかもしれません。
(外見は普通のアバターですし)
2007年12月11日
libsecondlifeサンプル - SIM統計情報の取得
SIMの統計情報(Ctrl+Shift+1で表示される情報)により、
SIMのFPS値やアバター数などを知ることが出来ます。
詳細は公式のSECOND LIFE HELPを参照してください。(ちょっと情報が古いようですが)
http://help.secondlife.com/jp/guides/stats.php
http://secondlife.com/app/help/guides/stats.php

現在いるSIMの統計情報を、client.Network.CurrentSim配下のStats構造体から取得できます。
取得のためのリクエストの発行は不要で、最新の情報のみが勝手に上記の構造体に格納されます。
(client.Settings.ENABLE_SIMSTATS はデフォルトでTrueになっています)
以下はサンプルコードです。
・libsecondlife0.2.0では、client.Network.CurrentSim の下に直接FPSなどの値が入っていました。
0.3.0からその下にStatsという構造体で格納されるようになりました。(Simulator.cs参照)
・ScriptTimeには小さい値が、OtherTimeには大きな値が出力されています。
値の入れ方が逆なのかもしれません。
フォーラム(http://forums.opensecondlife.org/ )は落ちたままだし、
メーリングリストも動きがほとんどありません。
(サーバ移行でデータロスがあったとか投稿がありました)
復活を祈っています。
SIMのFPS値やアバター数などを知ることが出来ます。
詳細は公式のSECOND LIFE HELPを参照してください。(ちょっと情報が古いようですが)
http://help.secondlife.com/jp/guides/stats.php
http://secondlife.com/app/help/guides/stats.php

現在いるSIMの統計情報を、client.Network.CurrentSim配下のStats構造体から取得できます。
取得のためのリクエストの発行は不要で、最新の情報のみが勝手に上記の構造体に格納されます。
(client.Settings.ENABLE_SIMSTATS はデフォルトでTrueになっています)
以下はサンプルコードです。
#libsecondlifeのロード
import clr
clr.AddReferenceToFile("libsecondlife.dll")
import libsecondlife
import time
#ログイン情報の設定
firstName = 'abcd' #苗字
lastName = 'efgh' #名前
passWord = 'ijkl' #パスワード
#初期設定、
client = libsecondlife.SecondLife()
#client.Settings.ENABLE_SIMSTATS = True
#接続
client.Network.Login(firstName, lastName, passWord, '', '')
time.sleep(10)
#実際の処理(SIM統計情報の取得)
sim = client.Network.CurrentSim
attrList = [
#debug-Simulator
'Dilation', #Time Dilation
'FPS', #Sim FPS
'PhysicsFPS', #Physics FPS
'AgentUpdates', #Agent Updates/Sec
'Agents', #Main Agents
'ChildAgents', #Child Agents
'Objects', #Objects
'ScriptedObjects', #Active Objects
'ActiveScripts', #Active Scripts
'LSLIPS', #Script Perf
'INPPS', #Packets In
'OUTPPS', #Packets Out
'PendingDownloads', #Pending Downloads
'PendingUploads', #Pending Uploads
'UnackedBytes', #Total Unacked Bytes
#debug-Simulator-Time(ms)
'FrameTime', #Total Frame Time
'NetTime', #Net Time
'PhysicsTime', #Sim Time (Physics)
'OtherTime', #Sim Time (Other)
'AgentTime', #Agent Time ##'Agent Time' not found. then LET 0.0
'ImageTime', #Images Time
'ScriptTime', #Script Time
]
for i in (attrList):
try:
val = eval('sim.Stats.%s' % (i) )
except AttributeError:
print i, 'AttributeError'
continue
print i, val
#切断
client.Network.Logout()
・libsecondlife0.2.0では、client.Network.CurrentSim の下に直接FPSなどの値が入っていました。
0.3.0からその下にStatsという構造体で格納されるようになりました。(Simulator.cs参照)
・ScriptTimeには小さい値が、OtherTimeには大きな値が出力されています。
値の入れ方が逆なのかもしれません。
フォーラム(http://forums.opensecondlife.org/ )は落ちたままだし、
メーリングリストも動きがほとんどありません。
(サーバ移行でデータロスがあったとか投稿がありました)
復活を祈っています。
2007年12月07日
libsecondlifeサンプル - テレポートと現在位置
テレポートを使ってアバターを遠く離れた場所に短時間で移動させることができます。
テレポート先の指定には2つの方法があります。
(1)SIM名とSIM内の位置
(2)ランドマークのUUID
順に説明します。
(1)SIM名とSIM内の位置を指定してテレポートする
SIM名の文字列と、SIM内の位置をベクトル型で指定してテレポートします。
例:Karuizawaシムの145, 250, 22 にテレポートする場合
(2)ランドマークのUUIDを指定してテレポートする
UUIDをUUID型で指定してテレポートします。
あらかじめ公式ビューアでインベントリからランドマークを探して、
右クリックして"Copy Asset UUID"を選んでUUIDを取得しておくとよいでしょう。
テレポート時に何かしたい場合は、以下のようにOnTeleportイベントをハンドルできます。
client.Self.OnTeleport += libsecondlife.AgentManager.TeleportCallback(teleportHandler)
イベントハンドラ側は3つの引数(message, status, flags)を持ちます。
例えば以下のような情報を得られます。
テレポートの開始と終了で2回は呼ばれるので注意が必要です。
例1:ランドマークを使ってテレポートを開始
message= Teleport started
status= Start
flags= ViaLandmark
例2:SIM名と位置を指定したテレポートが完了
message = Teleport finished
status = Finished
flags = ViaLocation
以下はサンプルコードです。
イベントクラスを定義していますが、実際は使っていません(手抜き^^;)
テレポート先の指定には2つの方法があります。
(1)SIM名とSIM内の位置
(2)ランドマークのUUID
順に説明します。
(1)SIM名とSIM内の位置を指定してテレポートする
SIM名の文字列と、SIM内の位置をベクトル型で指定してテレポートします。
例:Karuizawaシムの145, 250, 22 にテレポートする場合
simName = 'Karuizawa'
pos = libsecondlife.LLVector3(145, 250, 22)
client.Self.Teleport(simName, pos)
(2)ランドマークのUUIDを指定してテレポートする
UUIDをUUID型で指定してテレポートします。
あらかじめ公式ビューアでインベントリからランドマークを探して、
右クリックして"Copy Asset UUID"を選んでUUIDを取得しておくとよいでしょう。
lmUuid = libsecondlife.LLUUID('51daae92-4279-3530-82a6-349fe31a87bb')
client.Self.Teleport(lmUuid)
テレポート時に何かしたい場合は、以下のようにOnTeleportイベントをハンドルできます。
client.Self.OnTeleport += libsecondlife.AgentManager.TeleportCallback(teleportHandler)
イベントハンドラ側は3つの引数(message, status, flags)を持ちます。
例えば以下のような情報を得られます。
テレポートの開始と終了で2回は呼ばれるので注意が必要です。
例1:ランドマークを使ってテレポートを開始
message= Teleport started
status= Start
flags= ViaLandmark
例2:SIM名と位置を指定したテレポートが完了
message = Teleport finished
status = Finished
flags = ViaLocation
以下はサンプルコードです。
イベントクラスを定義していますが、実際は使っていません(手抜き^^;)
#libsecondlifeのロード
import clr
clr.AddReferenceToFile("libsecondlife.dll")
import libsecondlife
import time
#ログイン情報の設定
firstName = 'abcd' #苗字
lastName = 'efgh' #名前
passWord = 'ijkl' #パスワード
#イベント待ち合わせ用クラスの定義
class EventTracker:
def __init__(self):
self.data=False
def Clear(self):
self.data=False
def Set(self):
self.data=True
def Wait(self):
while not self.data:
time.sleep(0.1)
#テレポートイベント処理用ハンドラの定義
def teleportHandler(message, status, flags):
print 'message=', message
print 'status=', status
print 'flags=', flags
event.Set()
#現在位置を表示する関数の定義
def printCurrentLocation():
global client
print 'current sim =', client.Network.CurrentSim.Name, ',',
print 'pos =', client.Self.Position.ToString()
#初期設定、
event = EventTracker()
client = libsecondlife.SecondLife()
client.Self.OnTeleport += libsecondlife.AgentManager.TeleportCallback(teleportHandler)
#接続
client.Network.Login(firstName, lastName, passWord, '', '')
#実際の処理(テレポートと現在位置の取得)
#(1)SIM名とSIM内の位置を指定してテレポートする
time.sleep(10)
simName = 'Karuizawa'
pos = libsecondlife.LLVector3(145, 250, 22)
client.Self.Teleport(simName, pos)
#現在位置の表示
time.sleep(10)
printCurrentLocation()
#(2)ランドマークのUUIDを指定しててレポートする
time.sleep(10)
lmUuid = libsecondlife.LLUUID('51daae92-4279-3530-82a6-349fe31a87bb')
client.Self.Teleport(lmUuid)
#現在位置の表示
time.sleep(10)
printCurrentLocation()
#切断
client.Network.Logout()
2007年12月05日
libsecondlifeサンプル - 所持金照会
Self.RequestBalance() と Self.OnBalanceUpdated を使って、
アバターの所持金を調べることができます。
以下のページがとても参考になります。
このページが無ければ私もlibsecondlifeをさわる気になりませんでした。ありがとうございます。
SecondLifeのボットを5分で書く方法 - TokuLog 改め だまってコードを書けよハゲ
http://d.hatena.ne.jp/tokuhirom/20070921/1190371544
では所持金照会のサンプルです。
クライアントによる所持金照会の要求と、サーバによる応答は非同期です。
ポイントは以下の2つです。
(1)イベントハンドラ(コールバック関数)
41行目で、所持金照会の要求をサーバに投げています。
実際の処理は、所持金照会の要求に応答があったときに呼び出されるイベントハンドラで行います。
24行目でそのハンドラの定義を行い、34行目でハンドラを登録して、使えるようにします
(2)イベントの待ち合わせ
イベントの発生を待ち合わせるため、EventTrackerクラスをグローバル変数として使用します。
具体的には、
31行目でeventという名で(グローバル変数として)実体化し、
BalanceHandler関数内でも26行目でglobal命令文を使ってeventをグローバル変数として扱っています。
待ち合わせの流れは、
40行目のevent.Clear()でフラグを下げてから要求を出し、42行目でevent.Wait()でフラグが上がるのを待ちます。
イベントが発生すると、25行目のBalanceHandler関数が呼ばれ、
その関数の最後(28行目)でフラグを上げます。

間違いの指摘や不明点の質問を歓迎します。
アバターの所持金を調べることができます。
以下のページがとても参考になります。
このページが無ければ私もlibsecondlifeをさわる気になりませんでした。ありがとうございます。
SecondLifeのボットを5分で書く方法 - TokuLog 改め だまってコードを書けよハゲ
http://d.hatena.ne.jp/tokuhirom/20070921/1190371544
では所持金照会のサンプルです。
#libsecondlifeのロード
import clr
clr.AddReferenceToFile("libsecondlife.dll")
import libsecondlife
import time
#ログイン情報の設定
firstName = 'abcd' #苗字
lastName = 'efgh' #名前
passWord = 'ejkl' #パスワード
#イベント待ち合わせ用クラスの定義
class EventTracker:
def __init__(self):
self.data=False
def Clear(self):
self.data=False
def Set(self):
self.data=True
def Wait(self):
while not self.data:
time.sleep(0.1)
#所持金要求イベント処理用ハンドラの定義
def BalanceHandler(balance):
global event
print 'balance=', balance
event.Set()
#初期設定、
event = EventTracker()
client = libsecondlife.SecondLife()
#client.Self.OnBalanceUpdated += libsecondlife.MainAvatar.BalanceCallback(BalanceHandler) #ver0.2.0
client.Self.OnBalanceUpdated += libsecondlife.AgentManager.BalanceCallback(BalanceHandler) #ver0.3.0
#接続
client.Network.Login(firstName, lastName, passWord, '', '')
#実際の処理(残高照会)
event.Clear()
client.Self.RequestBalance()
event.Wait()
#切断
client.Network.Logout()
クライアントによる所持金照会の要求と、サーバによる応答は非同期です。
ポイントは以下の2つです。
(1)イベントハンドラ(コールバック関数)
41行目で、所持金照会の要求をサーバに投げています。
実際の処理は、所持金照会の要求に応答があったときに呼び出されるイベントハンドラで行います。
24行目でそのハンドラの定義を行い、34行目でハンドラを登録して、使えるようにします
(2)イベントの待ち合わせ
イベントの発生を待ち合わせるため、EventTrackerクラスをグローバル変数として使用します。
具体的には、
31行目でeventという名で(グローバル変数として)実体化し、
BalanceHandler関数内でも26行目でglobal命令文を使ってeventをグローバル変数として扱っています。
待ち合わせの流れは、
40行目のevent.Clear()でフラグを下げてから要求を出し、42行目でevent.Wait()でフラグが上がるのを待ちます。
イベントが発生すると、25行目のBalanceHandler関数が呼ばれ、
その関数の最後(28行目)でフラグを上げます。

間違いの指摘や不明点の質問を歓迎します。
2007年12月04日
libsecondlifeサンプル - 接続と切断
思うところがあって、いったんSLのアイテム収集のほうは
注力するエネルギーを減らして、
libsecondlifeのサンプルをまとめます。といっても、分かっている範囲の、
接続・切断、残高照会(他のかたのページにあったやつの劣化コピー^^;)、
テレポート、チャットの受信、統計情報の取得、新オブジェクトの情報、
指定オブジェクトの詳細取得、といったあたりです。
まずは、環境の紹介から。
WindowsXP Home Edition SP2 (たまにWindows2000SP2)
IronPython 1.1 (1.1) on .NET 2.0.50727.832 (FePy)
libsecondlife 0.3.0 (11/30に0.3.1が出ましたが、まだ移行してません^^;。)
libsecondlifeは0.2と0.3でクラス内のメンバ名とかが大きく変わっているので、
今からやるなら0.3.1がお勧めです。
まだバージョンアップで大きく変わる時期なので、適宜追随してくださいな。
では、接続と切断のサンプルです。
1-5行目:libsecondlifeを.Net経由でロードして、この言語から使えるようにします。
6-10行目:ログインに必要な最低限の情報をあらかじめ変数に入れます。
11-14行目:ライブラリを使ってSecondLifeに接続します。
16-18行目:30秒間何もしません。
19-20行目:ライブラリを使ってSecondLifeから切断します。
ポイントは、13行目の接続、20行目の切断です。
●接続は13行目です。
client.Network.Login(firstName, lastName, passWord, '', '')
第1引数:ログインするアバターのファースト・ネーム
第2引数:ログインするアバターのファミリー・ネーム
第3引数:ログインするアバターのパスワード
第4引数:プログラム名
第5引数:メールアドレス
●切断は20行目です。
client.Network.Logout()
引数はありません。
20行程度のコードで接続、切断が可能です。
実際の処理はコールバック関数を登録して非同期で行う場合が多いです。
次はコールバック関数を使った処理を書く予定です。
P.S.ソースコードを引用文(blockquote)以外で表示する方法をご存知の方がいらっしゃいましたら教えてください。
注力するエネルギーを減らして、
libsecondlifeのサンプルをまとめます。といっても、分かっている範囲の、
接続・切断、残高照会(他のかたのページにあったやつの劣化コピー^^;)、
テレポート、チャットの受信、統計情報の取得、新オブジェクトの情報、
指定オブジェクトの詳細取得、といったあたりです。
まずは、環境の紹介から。
WindowsXP Home Edition SP2 (たまにWindows2000SP2)
IronPython 1.1 (1.1) on .NET 2.0.50727.832 (FePy)
libsecondlife 0.3.0 (11/30に0.3.1が出ましたが、まだ移行してません^^;。)
libsecondlifeは0.2と0.3でクラス内のメンバ名とかが大きく変わっているので、
今からやるなら0.3.1がお勧めです。
まだバージョンアップで大きく変わる時期なので、適宜追随してくださいな。
では、接続と切断のサンプルです。
#libsecondlifeのロード
import clr
clr.AddReferenceToFile("libsecondlife.dll")
import libsecondlife
#ログイン情報の設定
firstName = 'abcd' #苗字
lastName = 'efgh' #名前
passWord = 'ijkl' #パスワード
#接続
client = libsecondlife.SecondLife()
client.Network.Login(firstName, lastName, passWord, '', '')
#実際の処理(ここでは単なるsleep)
import time
time.sleep(30)
#切断
client.Network.Logout()
1-5行目:libsecondlifeを.Net経由でロードして、この言語から使えるようにします。
6-10行目:ログインに必要な最低限の情報をあらかじめ変数に入れます。
11-14行目:ライブラリを使ってSecondLifeに接続します。
16-18行目:30秒間何もしません。
19-20行目:ライブラリを使ってSecondLifeから切断します。
ポイントは、13行目の接続、20行目の切断です。
●接続は13行目です。
client.Network.Login(firstName, lastName, passWord, '', '')
第1引数:ログインするアバターのファースト・ネーム
第2引数:ログインするアバターのファミリー・ネーム
第3引数:ログインするアバターのパスワード
第4引数:プログラム名
第5引数:メールアドレス
●切断は20行目です。
client.Network.Logout()
引数はありません。
20行程度のコードで接続、切断が可能です。
実際の処理はコールバック関数を登録して非同期で行う場合が多いです。
次はコールバック関数を使った処理を書く予定です。
P.S.ソースコードを引用文(blockquote)以外で表示する方法をご存知の方がいらっしゃいましたら教えてください。